1.NSIndexPath初始化
NSIndexPath*indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
2.监听textField输入字符串长度
[textaddTarget:selfaction:@selector(textFieldDidChange:)forControlEvents:UIControlEventEditingChanged];
-(void)textFieldDidChange :(UITextField*)theTextField{
if(theTextField.text.length==11) {
}
}
3.iOS去除Plain样式TableView底部多余的分割线
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
4.导航栏pop回指定控制器
for(UIViewController*temp in self.navigationController.viewControllers) {
if([temp isKindOfClass:NSClassFromString(@"xx")]) {
[self.navigationControllerpopToViewController:tempanimated:YES];
}
}
UIViewController *viewCtl = self.navigationController.viewControllers[2];
[self.navigationController popToViewController:viewCtl animated:YES];
5.两个或多个网络请求,全部返回后才可进行下一步操作(比如刷新页面UI等),需搭配使用线程组以及信号量
dispatch_group_t lxgGroup = dispatch_group_create();/* 创建多线程组 */
/* 创建并行队列 */
dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/*异步执行任务*/
dispatch_group_async(lxgGroup, queue, ^{
[self loadData:lxg parms:@"10059" data:dic];
});
dispatch_group_async(lxgGroup, queue, ^{
[self loadTwoData:lxg parms:@"10231" data:dic];
});
/*线程组内任务执行完毕,获取通知*/
dispatch_group_notify(lxgGroup, dispatch_get_main_queue(), ^{
[self.table reloadData];
[self.view hideHUD];
[self.table.mj_header endRefreshing];
});
- (void)loadData:(LXGNetWorkQuery*)lxg parms:(NSString*)parms data:(NSMutableDictionary*)dic
{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);/* 创建信号量 */
[lxg AFrequestData:parms
HttpMethod:@"POST"
params:dic
completionHandle:^(id result) {
dispatch_semaphore_signal(sema);/* 发送信号量 */
} errorHandle:^(NSError *result) {
[self.view showError:@"网络错误"];
dispatch_semaphore_signal(sema);/* 发送信号量 */
}];
/* 等待信号,相当于堵塞线程、和线程锁功能相似 */
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
6.删除单元格方法及注意事项
[tableView deleteRowsAtIndexPaths:
[NSArray arrayWithObject:indexPath] withRowAnimation:
UITableViewRowAnimationLeft];
/**此方法为删除一行cell的方法,同步删除数据源这种操作就不提了,
有个坑点就是,如果删除的本行cell,是这一组的最后一个cell,切记一定要调用下面的方法删除本组,否则会崩溃*/
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationLeft];
7.设置Lable部分文字属性(文字大小,颜色)
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@元",_model.price]];
// 设置颜色
[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(9, _model.price.length+1)];
//设置文字大小
[string addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:35]
range:NSMakeRange(0 , _model.price.length)];
_priceLable.attributedText = string;
8.将颜色转成图片
- (UIImage *)createImageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0.0f,0.0f,1.0f,1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context =UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *myImage =UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return myImage;
}
9.UILable大小计算方法
CGSize titleSize = [str boundingRectWithSize:CGSizeMake((Screen_width-30),MAXFLOAT)options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]}context:nil].size;
10.RunTime交换方法初级使用
应用场景是这样的:A页面有一个GCD定时器,控制A页面lable的秒数跳动,此时需要跳转到B页面,B页面也有一个lable需要同步跳动,现在需要A跳转的B页面后,A的定时器控制B页面lable的跳动,当返回A页面的时候则定时器控制A页面lable跳动。代码如下:
//本页面开启定时器
- (void)startTime
{
// GCD定时器
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0); //每秒执行
WEAKSELF;
dispatch_source_set_event_handler(_timer, ^{
[weakSelf quesstionTimeAction];
});
// 开启定时器
dispatch_resume(_timer);
}
/** 跳转到下一个页面 */
- (void)dtkAction
{
AnswerSheetCtr*answer = [[AnswerSheetCtr alloc] init];
UILabel*titleLable = (UILabel*)self.navigationItem.titleView;
answer.time = titleLable.text;
[self.navigationController pushViewController:answer animated:YES];
WEAKSELF;
[answer setBlock:^{
// 返回本页面后再次交换定时器方法
[weakSelf exChangeFunction];
}];
[self exChangeFunction];
}
/** 交换定时器方法,跳转到答题卡页面前,定时器控制本页面的时间跳动,跳转到答题卡后,定时器控制答题卡页面时间跳动 */
- (void)exChangeFunction
{
Method method1 = class_getInstanceMethod([QuestionController class], @selector(quesstionTimeAction));
Method method2 = class_getInstanceMethod([QuestionController class], @selector(questionAnswerAction));
method_exchangeImplementations(method1, method2);
}
11.sizeToFit与sizeThatFits的使用和区别
sizeToFit会自动算出lable的size,并且调用sizeToFit会自动改变自身size
sizeThatFits也会自动算出size,但是不会自动改变自身size
12.cocopods新源域名:https://gems.ruby-china.com/
13.替换工程内所有Lable的部分文字
+ (void)initialize
{
Method setText =class_getInstanceMethod([UILabel class], @selector(setText:));
Method setTextMySelf =class_getInstanceMethod([self class],@selector(setTextHooked:));
// 将目标函数的原实现绑定到setTextOriginalImplemention方法上
IMP setTextImp =method_getImplementation(setText);
class_addMethod([UILabel class], @selector(setTextOriginal:), setTextImp,method_getTypeEncoding(setText));
//然后用我们自己的函数的实现,替换目标函数对应的实现
IMP setTextMySelfImp =method_getImplementation(setTextMySelf);
class_replaceMethod([UILabel class], @selector(setText:), setTextMySelfImp,method_getTypeEncoding(setText));
}
- (void)setTextHooked:(NSString *)string
{
string = [string stringByReplacingOccurrencesOfString:@"测试" withString:@"小刚"];
[self performSelector:@selector(setTextOriginal:) withObject:string];
}
14.图片文件压缩
//文件压缩(包含图片文件压缩,类似于ZIP、RARg格式的压缩,只缩小文件大小,不会失帧,加载图片的时候会还原图片大小,所以一般只用于存储、上传)
- (void)fileCompression
{
UIImage*oldImage = [UIImage imageNamed:@"XX"];
/* 此处转换图片为data格式 */
NSData*oldData = UIImagePNGRepresentation(oldImage);
NSString*oldImageLength = [self getImageLength:oldData.length];
/* 此处压缩图片为jpg的data,文件体积比png会更小 */
NSData*newData = UIImageJPEGRepresentation(oldImage, 1);
NSString*newImageLength = [self getImageLength:newData.length];
NSLog(@"%@=====%@",oldImageLength,newImageLength);
CGFloat xRate = 1;
//比如说,希望图片文件压缩到50KB,xRate为压缩倍数示例,其实在实际使用中可以直接使用确定的常量
while (newData.length > 50*1024) {
xRate -= 0.1;
//一直压缩到50KB以下为止
newData = UIImageJPEGRepresentation(oldImage, xRate);
if (xRate < 0.1) {
break;
}
}
/* 最后根据压缩的data获取图片,或者直接进行上传、存储等操作 */
oldImage = [UIImage imageWithData:newData];
}
//此处获取图片长度
- (NSString*)getImageLength:(long)length
{
NSString*backStr = nil;
float size_kb = length/1024.0;
if (size_kb <1024) {
backStr = [NSString stringWithFormat:@"%0.2fkb",size_kb];
}else
{
backStr = [NSString stringWithFormat:@"%0.2fMB",size_kb/1024];
}
return backStr;
}
15.图片加载优化处理
假设有一张图片,大小是1.6MB,图片尺寸是3096X4128,使用“imageNamed”的图片加载方式进行加载,最后会占用手机多少内存呢?答案是48MB之多!(图片上一个像素是RGBA,也就是4个字节,4bytes * 3096 * 4128 = 48MB)试想多加载几张这样的大图片,APP必然会因为内存吃紧被杀掉,那么有什么方法解决呢?(不考虑imageWithContentsOfFile的方式)
//第一种图片处理方式,通过图片上下文做文章,此种方法尽量在主线程操作,比较耗费CPU,多张图片处理可能造成线程堵塞
- (void)scaleImage{
//取出一个3024*3024尺寸的图片
UIImage*image = [UIImage imageWithContentsOfFile:@"3024*3024"];
//改成200*200尺寸
CGSize imageSize = CGSizeMake(200, 200);
//开启图片上下文
UIGraphicsBeginImageContext(imageSize);
//更改
[image drawInRect:CGRectMake(0, 0, 200, 200)];
//生成新的图片
UIImage*newImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
}
//第二种图片处理方式,可放入子线程
- (void)scaleImageThead{
//取出一个3024*3024尺寸的图片
UIImage*image = [UIImage imageWithContentsOfFile:@"3024*3024"];
CGFloat width = 100;
CGFloat height = 100;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();//颜色空间
NSUInteger bytesPerPixel = 4;//RGBA 是4个字节,所以此处填4
NSUInteger bytesPerRow = bytesPerPixel*width;//这一行是多少字节,就是4*图片宽度
NSUInteger bitsPerComPonent = 8;
//生成上下文
CGContextRef context = CGBitmapContextCreate(nil, width, height, bitsPerComPonent, bytesPerRow, colorSpaceRef, kCGBitmapByteOrderDefault|kCGImageAlphaPremultipliedLast);
//根据上下文、图片、位置、生成新图片,注意此处如果不做处理,坐标会与正常坐标系相反,下文使用UIImageOrientationUp属性,确定了图片的方向
CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage*newImage = [UIImage imageWithCGImage:imageRef scale:UIScreen.mainScreen.scale orientation:UIImageOrientationUp];
}
16.关于tableView知识点的小tag,在tableView只有tableHeaderView而没有cell的时候 tableView是不能滑动的(即没有数据的时候),如果要滑动,需要添加一个cell(可以使用默认图点击刷新的方法,或者加一个高度为0.01的透明cell)
17.个数相同的时候,数字、文字不对齐,可以考虑字体用等宽字体:
[UIFont monospacedDigitSystemFontOfSize:11 weight:UIFontWeightMedium];