美文网首页
iOS常用笔记

iOS常用笔记

作者: 龙子陵 | 来源:发表于2017-11-02 11:48 被阅读0次

    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)

    相关文章

      网友评论

          本文标题:iOS常用笔记

          本文链接:https://www.haomeiwen.com/subject/kmsopxtx.html