月圆之夜,紫禁之巅,一剑西来,天外飞仙。

0%

先看效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
主要代码:

NSDecimalNumber * number1 = [NSDecimalNumber decimalNumberWithString :@“12.5”];

NSDecimalNumber * number2 = [NSDecimalNumber decimalNumberWithString :@“2.5”];

// 加

NSDecimalNumber * sumNum = [number1 decimalNumberByAdding :number2];

// 减

NSDecimalNumber * subNum = [number1 decimalNumberBySubtracting :number2];

// 乘

NSDecimalNumber * multiNum = [number1 decimalNumberByMultiplyingBy :number2];

// 除

NSDecimalNumber * dividNum = [number1 decimalNumberByDividingBy :number2];

1
2
3
4
5
6
 将图片保存到本地
UIImageWriteToSavedPhotosAlbum(img, self , @selector(image:didFinishSavingWithError:contextInfo:), nil);
//图片保存成功后调用的方法
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
//图片保存成功的事件
}

1
在开发中,经常可以看见有这样的需求,就是一个方法要等另外一个方法执行完毕再做相对应的处理,比如说一些网络请求,需要根据上一个请求的返回值做相对应的处理再执行第二个请求,所以我们不能让两个请求同时去请求网络。下面通过GCD和NSOperationQueue来处理这个问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
GCD方法:
//创建信号量
__block dispatch_semaphore_t test = dispatch_semaphore_create(0);

//创建队列
dispatch_queue_t queue = dispatch_queue_create("testBlock", NULL);

dispatch_async(queue, ^{

for (int i = 0; i< 4; i++)
{
NSLog(@"i的值是:%d",i);

tempStr = [NSString stringWithFormat:@"%d",i];
}
//发送通知

dispatch_semaphore_signal(test);


});

//信号量等待
dispatch_semaphore_wait(test, DISPATCH_TIME_FOREVER);

if([tempStr isEqualToString:@"5"])
{
for (int j = 0; j<5; j++)
{

NSLog(@"j的值是:%d",j);


}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
NSOperationQueue 方法
//创建一个队列
NSOperationQueue * queueeTest = [[NSOperationQueue alloc]init];

//设置最线程数

queueeTest.maxConcurrentOperationCount = 4;

//创建一个a操作
NSBlockOperation * optionA = [NSBlockOperation blockOperationWithBlock:^{

for (int i = 0; i<10000; i++)
{
NSLog(@"i的值是:%d",i);
}
}];

//创建一个b操作
NSBlockOperation * optionB = [NSBlockOperation blockOperationWithBlock:^{

for (int j = 0; j<20000; j++)
{
NSLog(@"j的值是:%d",j);
}
}];

//B操作依赖于a操作
[optionB addDependency:optionA];
//分别加入队列

[queueeTest addOperation:optionA];

[queueeTest addOperation:optionB];

1
在项目中做了iOS 11的适配之后发现以前项目中有些地方做了导航栏透明的设置在新系统上失效了。在细查之下发现新系统导航栏的层级结构有所变化。修改方法如下:

iOS 11 以前设置导航栏透明

1
[[self.navigationController.navigationBar subviews] objectAtIndex:0].alpha = 0;

iOS 11 设置导航栏透明

1
2
3
[[[[self.navigationController.navigationBar subviews] objectAtIndex:0] subviews] objectAtIndex:1].alpha = 0;

[[[[[self.navigationController.navigationBar subviews] objectAtIndex:0] subviews] objectAtIndex:0] setHidden:YES];

仅个人见解,如有错误请见谅!

倒计时按钮在项目中经常用到,为了使用方便我做了简单的封装。
下面直接上代码。

1
2
3
4
5
6
7
8
9
10
#import <UIKit/UIKit.h>

typedef void(^setBtnAction)();

@interface countdownButton : UIButton

//倒计时开始回调
@property(nonatomic,strong)setBtnAction setBtnAction;

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#import "countdownButton.h"

@interface countdownButton()

@property(nonatomic,strong)UIButton * btn;

@end

@implementation countdownButton
{

NSInteger secondsCountDown;
NSTimer * countDownTimer;

}
-(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];

if (self)
{
secondsCountDown = 60;

[self setBtnUI];
}

return self;
}

-(void)setBtnUI
{

[self setBackgroundColor:[UIColor orangeColor]];

[self setTitle:@"获取验证码" forState:UIControlStateNormal];

[self.titleLabel setFont:[UIFont systemFontOfSize:14.0]];

[self addTarget:self action:@selector(countDownAction:) forControlEvents:UIControlEventTouchUpInside];
}

-(void)countDownAction:(UIButton *)sender
{

[self setTitle:[NSString stringWithFormat:@"%zd s",secondsCountDown] forState:UIControlStateNormal];

countDownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeFireMethod) userInfo:nil repeats:YES];

[self setEnabled:NO];

if(self.setBtnAction)
{
self.setBtnAction();
}

}

-(void)timeFireMethod
{
secondsCountDown--;

[self setTitle:[NSString stringWithFormat:@"%zd s",secondsCountDown] forState:UIControlStateNormal];

if (secondsCountDown<0)
{
[countDownTimer invalidate];

[self setEnabled:YES];

[self setTitle:@"获取验证码" forState:UIControlStateNormal];

secondsCountDown = 60;
}

}
@end

在需要使用倒计时按钮的地方初始化。
这里我在ViewController 中初始化,记得引入头文件。

1
#import "countdownButton.h"
1
2
3
4
5
6
7
8
9
10
11
12
countdownButton * btn = [[countdownButton alloc]initWithFrame:CGRectMake(100, 100, 90, 40)];

[btn setBackgroundColor:[UIColor purpleColor]];

[btn setSetBtnAction:^(){

//这里写入倒计时开始时需要执行的事件。
NSLog(@"倒计时开始");

}];

[self.view addSubview:btn];

demo 地址:https://github.com/xiaobai0134/XBCountDownButton

最近项目中需要集成支付宝支付功能,在此做一个简单的笔记。
集成支付宝支付需要以下几个步骤:

1
2
3
4
5
1、申请支付宝支付用到的AppKey;
2、添加支付宝SDK
3、调用方法发送订单信息
4、设置URL Type
5、添加回调方法

第一步在此略过。
第二步下载AlipaySDK,下载后文件夹中有AlipaySDK.bundle 和AlipaySDK.framework 两个文件,添加到工程中进行编译,如有缺少的文件,在进行添加。
第三步封装订单信息,调用如下方法。

1
2
3
4
5
6
导入头文件#import <AlipaySDK/AlipaySDK.h>

NSString *appID = 申请的AppID;

NSString *rsa2PrivateKey = @"";
NSString *rsaPrivateKey = @"";

rsa2PrivateKey 与 rsaPrivateKey 为私钥,只需填入一个,简易用rsa2PrivateKey。获取 rsa2PrivateKey,建议使用支付宝提供的公私钥生成工具生成工具地址:

1
https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1
1
2
3
4
5
6
7
8

[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic){
NSLog(@"reslut ===>= %@",resultDic);}
}];

这里需要注意:
orderString 为订单信息,由后台返回。
appScheme 为跳转的URL 在Info-plist中定义

第四步设置URL type
这里写图片描述
第五步,添加回调方法。在AppDelegate.m中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
if ([url.host isEqualToString:@"safepay"]) {
// 支付跳转支付宝钱包进行支付,处理支付结果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];

// 授权跳转支付宝钱包进行支付,处理支付结果
[[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
// 解析 auth code
NSString *result = resultDic[@"result"];
NSString *authCode = nil;
if (result.length>0) {
NSArray *resultArr = [result componentsSeparatedByString:@"&"];
for (NSString *subResult in resultArr) {
if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
authCode = [subResult substringFromIndex:10];
break;
}
}
}
NSLog(@"授权结果 authCode = %@", authCode?:@"");
}];


}
return YES;
}

本文仅供学习,如有错误请见谅!

最近在写项目的时候项遇到到了图片上传的问题,在这里将所用到的方法记录下来。在这里用NSData数据流进行上传。
废话不多说直接上代码

1
当然在上传图片之前还需要在工程中添加AFN库。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
NSData * imageData = UIImageJPEGRepresentation(image, 0.1);

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
@"text/html",
@"image/jpeg",
@"image/png",
@"application/octet-stream",
@"text/json",
nil];
NSURLSessionDataTask *task = [manager POST:KReportImageUrl parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSData *imageDatas = imageData;

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@.jpg", str];
//上传的参数(上传图片,以文件流的格式)
[formData appendPartWithFileData:imageDatas
name:@"photo"
fileName:fileName
mimeType:@"image/jpeg"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
//上传进度

NSLog(@"%@",uploadProgress);

} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//上传成功
NSLog(@"上传成功");

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//上传失败
NSLog(@"上传失败========>%@",error);
}];

在iOS开发中,常常会碰到在列表中实现单选的功能,在tableView中,可以通过其自身来实现。

1
2
在这里定义tagIndex来标记当前选中的行
@property (assign, nonatomic) NSIndexPath *tagIndex;
1
在-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath这个方法中通过tagIndex来判断当前行是否被选中。
1
2
3
4
5
6
7
8
if(_tagIndex == indexPath)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
1
在-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath这个方法中
1
2
3
4
5
6
7
8
//如果是之前选中的,则取消选择
UITableViewCell *celled = [tableView cellForRowAtIndexPath:_tagIndex];
celled.accessoryType = UITableViewCellAccessoryNone;
//记录当前选中的位置
_tagIndex = indexPath;
//当前选择的打勾
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
1
如果想要改变对号的颜色,可用cell.TintColor来设置。

最近在项目中遇到这样一个问题,在自定义的通讯录中点击索引的时候对应的分组标题改变其状态(如改变其字体颜色、类型、字号等)。在网上找了很长时间但没找到可以使用的,这里有一个写的可以用的拿出来分享一下,写的不好还请见谅!

主要思路:

一、在工程中通过对数据源进行处理,使它们按照汉语拼音进行排序并按照拼音的第一个字母进行分组。

1
2
3
如:现在有数据源
self.tmpNameArr = [NSArray arrayWithObjects:@"Aorde",@"爱旅行的猫",@"张三丰",@"张道陵",@"李太白",@"八大山人",@"温庭筠",@"杜甫",@"王安石",@"李白",@"张三",@"重庆",@"重量",@"调节",@"调用",@"小白",@"小明",@"千珏",@"黄家驹", @"鼠标",@"hello",@"多美丽",@"肯德基",@"##",@"e才到家",@"方米",@"高明",@"icd",@"jeer",@"米杰",@"宁宁",@"盟们",@"彭明",@"任港南飞",@"他宝宝",@"袁浩",nil];
将它们进行分组后,建立2个数组,一个是排序后出现过得品应首字母数组也就是索引数组(indexArray),一个是排序号的结果数组(letterResultArr)。在这里排序分组用到了网上的ZYPinYinSearchLib 和 BMChineseStringSort。

二、用tableView来展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//section的titleHeader
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

return self.indexArray[section];
}
//section的titleHeader的高度
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return MDXFrom6(15);
}
//section行数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{

return self.indexArray.count;

}
//每组section个数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

return [self.letterResultArr[section] count];

}
//section右侧index数组
//右侧索引列表
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
return self.indexArray;
}
-(UITableViewCell * )tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * tongXunLuID = @"tongXunLuID";

tongXuLuTableViewCell * tongXunLuCell = [tableView dequeueReusableCellWithIdentifier:tongXunLuID];

if (!tongXunLuCell)
{
tongXunLuCell = [[tongXuLuTableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:tongXunLuID];

tongXunLuCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
Person *p = [[self.letterResultArr objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];

[tongXunLuCell.tmpNameLabel setText:[NSString stringWithFormat:@"%@",p.name]];
return tongXunLuCell;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return MDXFrom6(49);
}
#pragma mark -- tableView点击事件
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{//这里是tableViewcell 的点击事件
}

三、点击索引时改变对应section的状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
定义一个数组arr,在数据源分组完成后初始化并赋值
self.arr = [NSMutableArray array];
for (NSInteger i=0; i<self.letterResultArr.count; i++)
{
[self.arr addObject:@"1"];
}
设置滑动代理
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
[self.arr removeAllObjects];
for (NSInteger i=0; i<self.letterResultArr.count; i++) {

[self.arr addObject:@"1"];
}
}
设置点击索引的操作
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{

[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index] atScrollPosition:UITableViewScrollPositionTop animated:YES];

[tableView reloadData];
NSMutableArray *ar = [NSMutableArray arrayWithArray:self.arr];
[self.arr removeAllObjects];

//标记
for (NSInteger i=0; i<ar.count; i++)
{
if (i == index)
{
[self.arr addObject:@"2"];
}
else
{
[self.arr addObject:@"1"];
}

}
return index;
}

在自定义的view中改变状态
//section 自定义
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView* myView = [[UIView alloc] init];
myView.backgroundColor = RGB_Color(255, 255, 255);
self.sectionLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, KDeviceWidth, MDXFrom6(15))];
self.sectionLabel.textColor=[UIColor blackColor];
self.sectionLabel.backgroundColor = RGB_Color(181, 181, 181);
[self.sectionLabel setTextAlignment:NSTextAlignmentCenter];
self.sectionLabel.text=[self.indexArray objectAtIndex:section];


NSString *mod = self.arr[section];
if ([mod integerValue] == 2)
{
[self.sectionLabel setTextColor:[UIColor redColor]];
}
[myView addSubview:self.sectionLabel];

return myView;
}