iOS常用笔记

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];

你可能感兴趣的:(iOS常用笔记)