美文网首页
iOS 那些必备却又记不清的知识点...

iOS 那些必备却又记不清的知识点...

作者: iOS_July | 来源:发表于2019-05-07 20:16 被阅读0次
    内容较多,建议command + F,去吧:
    一、tableView刷新指定行
    //一个section刷新    
    NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:section];    
    [tableview reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];    
    //一个cell刷新    
    NSIndexPath *indexPath=[NSIndexPath indexPathForRow:row inSection:section];    
    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone]; 
    
    二、tableView胡乱漂移
    _tableView.estimatedRowHeight = 0;
    _tableView.estimatedSectionHeaderHeight = 0;
    _tableView.estimatedSectionFooterHeight = 0;
    
    三、模型 嵌套 模型数组
    • json类似于:
     NSArray *tempArr = @[@{@"checkProject":@"第一",@"status":@"-1",@"countList":
    @[
      @{@"checkContent":@"checkProject",@"status":@"-1"},
      @{@"checkContent":@"什么项目呀",@"status":@"0"},
      @{@"checkContent":@"喵喵喵",@"status":@"1"},
      @{@"checkContent":@"已执行",@"status":@"2"},
      @{@"checkContent":@"好的呀👌",@"status":@"3"},]},
                             @{@"checkProject":@"第二",@"status":@"-1",@"countList":@[
                                       @{@"checkContent":@"checkProject",@"status":@"-1"},
                                       @{@"checkContent":@"什么项目呀",@"status":@"0"},
                                       @{@"checkContent":@"喵喵喵",@"status":@"1"},
                                       @{@"checkContent":@"已执行",@"status":@"2"},
                                       @{@"checkContent":@"好的呀👌",@"status":@"3"},]},
                             @{@"checkProject":@"第三",@"status":@"-1",@"countList":@[
                                       @{@"checkContent":@"checkProject",@"status":@"-1"},
                                       @{@"checkContent":@"什么项目呀",@"status":@"0"},
                                       @{@"checkContent":@"喵喵喵",@"status":@"1"},
                                       @{@"checkContent":@"已执行",@"status":@"2"},
                                       @{@"checkContent":@"好的呀👌",@"status":@"3"},]},
                             @{@"checkProject":@"第四",@"status":@"-1",@"countList":@[
                                       @{@"checkContent":@"checkProject",@"status":@"-1"},
                                       @{@"checkContent":@"什么项目呀",@"status":@"0"},
                                       @{@"checkContent":@"喵喵喵",@"status":@"1"},
                                       @{@"checkContent":@"已执行",@"status":@"2"},
                                       @{@"checkContent":@"好的呀👌",@"status":@"3"},]}];
    
    • 除了tempArr本身可转成一个模型外,其中包含countList,也是一个模型。
    • 模型的 .h 中:
    //内部模型
    @interface EHSCheckPlanDetailCountListModel : NSObject
    
    /** status*/
    @property (nonatomic, copy) NSString * status;
    
    /** 检查项目名称*/
    @property (nonatomic, copy) NSString *checkProject;
    /** 检查内容*/
    @property (nonatomic, copy) NSString *checkContent;
    
    @end
    
    
    //外部模型
    @interface EHSCheckPlanDetailModel : NSObject
    /** status*/
    @property (nonatomic, copy) NSString * status;
    
    /** 检查项目名称*/
    @property (nonatomic, copy) NSString *checkProject;
    
    /** 嵌套model*/
    @property (nonatomic, strong) NSMutableArray *countList;
    
    @end
    
    • 这时候 是不能 直接使用的,需要在 .m 中,转换一下:
    @implementation EHSCheckPlanDetailCountListModel
    
    @end
    
    @implementation EHSCheckPlanDetailModel
    
    + (NSDictionary *)mj_objectClassInArray{
        return @{ @"countList" : [EHSCheckPlanDetailCountListModel class]};
    }
    
    @end
    
    四、模型转 id 等 关键字
    • .h中:
    /** id*/
    @property (nonatomic, copy) NSString *ID;
    
    • .m中:
    + (NSDictionary *)replacedKeyFromPropertyName{
        
        return @{@"ID":@"id"};
    }
    
    五、字符串截取
    //1.截取字符串
        
    NSString *string =@"123456789";
    NSString *str1 = [string substringToIndex:5];//截取 到 下标5之前的字符串
    NSLog(@"截取的值为:%@",str1);
    NSString *str2 = [string substringFromIndex:3];//从 下标3之后的字符串 开始截取
    NSLog(@"截取的值为:%@",str2);
    
    六、判断字符串是否包含字符&&截取
    if([@"abc" rangeOfString:@"a"].location !=NSNotFound) {
            NSLog(@"yes");
        }else {
            NSLog(@"no");
        }
    
    
    NSString *string =@"123456789";
    NSRange range = [string rangeOfString:@"4"];//匹配得到的下标
    NSLog(@"rang:%@",NSStringFromRange(range));
    string = [string substringWithRange:range];//截取范围内的字符串
    NSLog(@"截取的值为:%@",string);
    
    七、字符串分割为数组
    NSString *string =@"123456789";
    NSArray *array = [string componentsSeparatedByString:@"5"]; //从字符'5'中分隔成2个元素的数组
    NSLog(@"array:%@",array); 
    
    八、数组转字符串
    NSString *str = [arr componentsJoinedByString:@","];//以","为分隔符
    
    九、数组是否存在指定字符串
    NSString *str = @"12";
    NSArray *array=@[@"12",@"22",@"13",@"3567"];
    BOOL isbool = [array containsObject: str];
    
    十、通知传值
    • NSNotification
      通知中心传值,可以跨越多个页面传值, 一般多用在push后面的页面传给前面的页面
    • 思路:
    1. 在第一个界面建立一个通知中心, 通过通知中心,注册一个监听事件,写好接受通知的事件。
    2. 在第一个界面中的dealloc中, 将通知中心remove掉
    3. 在第二个界面中, 建立一个通知中心, 通过通知中心, 发送通知(发送通知的过程就是传值的过程,将要传输的值作为object的值传给第一个界面 )
    • 第一个页面:
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self registerNotification];
    }
    #pragma mark - --------- 通知相关 ---------
    - (void)registerNotification{
        //通知中心是个单例
        NSNotificationCenter *notiCenter = [NSNotificationCenter defaultCenter];
        // 注册一个监听事件。第三个参数的事件名, 系统用这个参数来区别不同事件。
        [notiCenter addObserver:self selector:@selector(receiveNotification:) name:kNotificationAddManPush object:nil];
       
    }
    - (void)receiveNotification:(NSNotification *)noti
    {
        // NSNotification 有三个属性,name, object, userInfo,其中最关键的object就是从第三个界面传来的数据。name就是通知事件的名字, userInfo一般是事件的信息(多个信息传递)。
        NSLog(@"%@ === %@ === %@", noti.object, noti.userInfo, noti.name);
    }
    - (void)dealloc
    {
        // 移除当前对象监听的事件
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    //[[NSNotificationCenter defaultCenter] removeObserver:self name:kNotificationAddManPush object:nil];
    }
    
    • 第二个界面:
    
    NSDictionary *dict = @{@"model":__weakSelf.dataList,@"name":smodel.employeeName};
    // 创建一个通知中心
    // 发送通知. 其中的 kNotificationAddManPush 填写第一界面的Name, 系统知道是第一界面来相应通知, object就是要传的值。 UserInfo是一个字典, 如果要用的话,提前定义一个字典, 可以通过这个来实现多个参数的传值使用。
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    //发送通知
    [center postNotificationName:kNotificationAddManPush object:@"人员选择" userInfo:dict];
    
    [self.navigationController popViewControllerAnimated:YES];
    
    十一、Domain=SDWebImageErrorDomain Code=0 "Downloaded image has 0 pixels" UserInfo
    • 先吐槽一下,当你知道答案后会让你不知所措
    • 在网页上可以打开,SDWebImage就是死活缓存不了,换一张其他的网图却又可以显示...
    • 有的说是请求头,但当你设置请求头之后,依旧是 返回0像素图片....真正原因其实是Cookies!
    • SDWebImageHandleCookies
      [cell.imgView sd_setImageWithURL:[NSURL URLWithString:imgUrl] placeholderImage:normalImg options:SDWebImageHandleCookies];
    十二、the document "units.h" could not be saved.you don't have permission
    • 我相信你已经在stackoverflow上逛了一会回来了,心情还美丽吗?
    • 我的解决办法是,关机、重启!关不了?那就暴力点呗~
    十三、pop返回到指定界面
    {
    EHSTroubleFillViewController *vc = [[EHSTroubleFillViewController alloc]init];
    [self PopToViewControllerWithVC:vc];
    }
    
    #pragma mark - ------- 返回到指定界面 -------
    - (void)PopToViewControllerWithVC:(UIViewController *)targetVC
    {
        UIViewController *target = nil;
        for (UIViewController * controller in self.navigationController.viewControllers) {
            if ([controller isKindOfClass:[targetVC class]]) {
                target = controller;
            }
        }
        if (target) {
            [self.navigationController popToViewController:target animated:YES];
        }
    }
    
    十四、Label计算显示百分数
    • 1.不需要保留小数 && 不要四舍五入
    float p = [model.studiedCount floatValue]/[model.totalCount floatValue];
        [self.progressView setProgress:p animated:YES];//我设置的进度条,可忽略
        CGFloat result = p * 100;
        if (result == 100) {
            self.learnLab.text = @"100%";
        }else{
            NSString *resultStr = [NSString stringWithFormat:@"%f",result];//避免.f会四舍五入的情况
            NSArray *tempA = [resultStr componentsSeparatedByString:@"."];
            self.learnLab.text = [NSString stringWithFormat:@"%@%%",tempA.firstObject];
        }
    
    • 2.需要保留小数 && 四舍五入
    float p = [model.count floatValue]/[model.allCount floatValue];
        CGFloat result = p * 100;
        if (result == 100) {
            self.percentageLab.text = @"100%";
        }else{
            self.percentageLab.text = [NSString stringWithFormat:@"%.1f%%",result];//需要保留小数 && 四舍五入
        }
    
    十五、Label置顶、置底显示
    • 当设置numberOfLines与相关高度之后,Label的内容在很多的情况下看不出异常,但是如果Label内容很少,不足以支撑换行,那么这时候情况就开始诡异了,它会垂直居中显示。
    • 改善:

    • Label扩展.h里:
    ///置顶显示
    - (void)setAlignmentTop;
    ///置底显示
    - (void)setAlignmentBottom;
    
    • Label扩展.m里
    ///置顶显示
    -(void)setAlignmentTop
    {
        // 对应字号的字体一行显示所占宽高
        CGSize fontSize = [self.text sizeWithAttributes:@{NSFontAttributeName:self.font}];
        // 多行所占 height*line
        double height = self.frame.size.height;
        // 显示范围实际宽度
        double width = self.frame.size.width;
        // 对应字号的内容实际所占范围
        CGSize stringSize = [self.text boundingRectWithSize:CGSizeMake(width, height) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:@{NSFontAttributeName:self.font} context:nil].size;
        // 剩余空行
        NSInteger line = (height - stringSize.height) / fontSize.height;
        // 用回车补齐
        for (int i = 0; i < line; i++) {
            
            self.text = [self.text stringByAppendingString:@"\n "];
        }
    }
    ///置底显示
    -(void)setAlignmentBottom
    {
        CGSize fontSize = [self.text sizeWithAttributes:@{NSFontAttributeName:self.font}];
        double height = fontSize.height*self.numberOfLines;
        double width = self.frame.size.width;
        CGSize stringSize = [self.text boundingRectWithSize:CGSizeMake(width, height) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.font} context:nil].size;
        
        NSInteger line = (height - stringSize.height) / fontSize.height;
        // 前面补齐换行符
        for (int i = 0; i < line; i++) {
            self.text = [NSString stringWithFormat:@" \n%@", self.text];
        }
    }
    
    十六、Label首行缩进
    #pragma mark - 首行缩进
    - (void)adjustLabelStyle:(UILabel *)label contentStr:(NSString *)contentStr
    {
        NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
        paraStyle.alignment = NSTextAlignmentLeft;  //对齐
        paraStyle.headIndent = 0.0f;//行首缩进
        //参数:(字体大小17号字乘以2,34f即首行空出两个字符)
        CGFloat emptylen = label.font.pointSize * 2;
        paraStyle.firstLineHeadIndent = emptylen;//首行缩进
        paraStyle.tailIndent = 0.0f;//行尾缩进
        paraStyle.lineSpacing = 2.0f;//行间距
        NSAttributedString *attrText = [[NSAttributedString alloc] initWithString:contentStr attributes:@{NSParagraphStyleAttributeName:paraStyle}];
        label.attributedText = attrText;
    }
    
    十七、绘制虚线间隔
    • image的扩展中,为类方法,如果不写在扩展里,或者用的场景较少,可直接改成类方法。
    /**
     返回一张 虚线 image
     
     @param imageView imageView
     @param lineColor lineColor
     @param vertical  是则 绘制垂直虚线/否则 为水平虚线
     @return image
     */
    + (UIImage *)imageWithLineWithImageView:(UIImageView *)imageView lineColor:(UIColor *)lineColor vertical:(BOOL)vertical{
        CGFloat width = imageView.frame.size.width;
        CGFloat height = imageView.frame.size.height;
        //画线
        if (vertical) {
            UIGraphicsBeginImageContext(imageView.frame.size);
            [imageView.image drawInRect:CGRectMake(0, 0, width, height)];
            CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
            CGFloat lengths[] = {5,5};//虚线的长度设置
            CGContextRef context =UIGraphicsGetCurrentContext();
            CGContextBeginPath(context);
            CGContextSetLineWidth(context,1);
            CGContextSetStrokeColorWithColor(context, lineColor.CGColor);
            CGContextSetLineDash(context, 0, lengths,2);
            CGContextMoveToPoint(context, 0, 0);
            CGContextAddLineToPoint(context, 0,height);
            CGContextStrokePath(context);
            CGContextClosePath(context);
        }else{
            UIGraphicsBeginImageContext(imageView.frame.size);
            [imageView.image drawInRect:CGRectMake(0, 0, width, height)];
            CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
            CGFloat lengths[] = {5,5};//虚线的长度设置
            CGContextRef line = UIGraphicsGetCurrentContext();
            CGContextSetStrokeColorWithColor(line, lineColor.CGColor);
            CGContextSetLineDash(line, 0, lengths, 1);
            CGContextMoveToPoint(line, 0, 1);
            CGContextAddLineToPoint(line, width-5, 1);
            CGContextStrokePath(line);
        }
        
        return  UIGraphicsGetImageFromCurrentImageContext();
    }
    
    • 使用:
    UIImageView *padV2 = [[UIImageView alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(examineeBtn.frame)+10, WIDTH, 1)];
        padV2.image = [UIImage imageWithLineWithImageView:padV2 lineColor:JHRGB(200, 200, 200)];
        [contentView addSubview:padV2];
    
    十八、简单的GCD延时执行
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    
    });
    
    十九、删除Xcode的多余证书
    • 前往 ~/Library/MobileDevice/Provisioning Profiles
    二十、UITextField 修改Placeholder颜色
    // "通过KVC修改占位文字的颜色"
        [textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
    

    相关文章

      网友评论

          本文标题:iOS 那些必备却又记不清的知识点...

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