iOS tableView坑集

作者: 山杨 | 来源:发表于2017-10-10 14:31 被阅读439次

    1. 消除plain样式的多余的(没有数据的)cell

    self.tableView.tableFooterView = [UIView new];
    

    2. 异步加载cell的内容, 优化tableView的性能

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        
        CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseID forIndexPath:indexPath];
        if (!cell) {
            
            cell = [CustomCell cell];
        }
        // 在此处进行数据异步加载
        [self asyncLoadingCellWithHandler:^(CustomModel *result) {
            dispatch_async(dispatch_get_main_queue(), ^{
    
               cell.model = result;
            });
         }];
        return cell;
    }
    

    3. cell的插入/删除/刷新/移动

    // 需要用到的相关方法
    - (void)beginUpdates;
    - (void)endUpdates;
    
    - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
    - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
    - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
    - (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection NS_AVAILABLE_IOS(5_0);
    
    - (void)insertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
    - (void)deleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
    - (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
    - (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0);
    
    // 获取当前cell所在的组数
    NSUInteger sectionNum = indexPath.section;
    // 查看当前数据所在的组中的行数
    NSUInteger rowsCount  = [self.tableView numberOfRowsInSection:sectionNum];
    // 刷新数据源: 增加数据/删除数据/修改数据/移动数据
    ...
    // 开始执行UI操作
    [self.tableView beginUpdates];
    例: 
    1. 删除cell
    /*
      如果操作的tableView是plain样式, 在删除cell的时候需要考虑到当前组中是否只有一个cell,
      如果是, 需要在执行 deleteRowsAtIndexPaths:withRowAnimation: 方法的时候同时执行 deleteSections:withRowAnimation: 否则会一直报错
    */  
    if (rowsCount == 1) {
    
        NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:indexPath.section];
        [self.tableView deleteSections:indexSet withRowAnimation:UITableViewRowAnimationFade];
    }
    [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    2. 插入cell
    ...
    3. 更新cell
    ...
    4. 移动cell
    ...
    [self.tableView endUpdates];
    

    4. plain样式的组头标题会自动悬停, group样式的组头标题不会自动悬停

    在此方法中设置组头标题内容
    - (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
    

    5. 自定义左滑cell, 出现编辑按钮的样式

    iOS 11以前, 在自定义cell的- (void)layoutSubviews方法中自定义左滑cell后的编辑按钮样式

    - (void)layoutSubviews {
        [super layoutSubviews];
        
        for (UIView *subV in self.subviews.firstObject.subviews) {
            
            if ([subV isKindOfClass:NSClassFromString(@"_UITableViewCellActionButton")]) {
                
                UILabel *buttonLabel = subV.subviews.firstObject;// UIButtonLabel
                [buttonLabel removeFromSuperview];
                // 添加文字
                NSString *titleStr = buttonLabel.text;
                CGSize titleSize = [titleStr boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{
                                                                                                                                                            NSFontAttributeName:[UIFont systemFontOfSize:12]                                                                              } context:nil].size;
                CGFloat imageWH  = 18;
                CGFloat topAndBottomMargin = 14;
                CGFloat labelX   = (CGRectGetWidth(subV.frame) - titleSize.width) * 0.5;
                CGFloat labelY   = CGRectGetHeight(subV.frame) - (topAndBottomMargin + titleSize.height);
                CATextLayer *titleLayer    = [CATextLayer layer];
                titleLayer.contentsScale   = 2;
                titleLayer.frame           = CGRectMake(labelX, labelY, titleSize.width, titleSize.height);
                titleLayer.string          = titleStr;
                titleLayer.fontSize        = 12;
                titleLayer.foregroundColor = [UIColor whiteColor].CGColor;
                [subV.layer addSublayer:titleLayer];
                
                // 添加图片
                CGFloat imageX = (CGRectGetWidth(subV.frame) - imageWH) * 0.5;
                CGFloat imageY = topAndBottomMargin;
                CGRect imageRect = CGRectMake(imageX, imageY, imageWH, imageWH);
                
                UIImage *image = nil;
                if ([titleStr isEqualToString:@"删除"]) {
                    
                    image = [UIImage imageNamed:@"delete_icon"];
                }
                if ([titleStr isEqualToString:@"发送"]) {
    
                    image = [UIImage imageNamed:@"send_icon"];
                }
                CALayer *layer = [CALayer layer];
                layer.frame = imageRect;
                layer.contents = (id)image.CGImage;
                [subV.layer addSublayer:layer];
            }
        }
    }
    

    iOS 11以后, 在tableView的- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath中自定义左滑cell后的编辑按钮样式

    - (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
        
        for (UIView *subV in self.tableView.subviews) {
            if ([subV isKindOfClass:NSClassFromString(@"UISwipeActionPullView")]) {
                for (UIButton *actionBtn in subV.subviews) {
                    if ([actionBtn isKindOfClass:NSClassFromString(@"UISwipeActionStandardButton")]) {
                        
                        // 添加文字
                        NSString *titleStr         = actionBtn.titleLabel.text;
                        CGSize titleSize           = [titleStr boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{
                                                                                                                                                                    NSFontAttributeName:[UIFont systemFontOfSize:12]                                                                              } context:nil].size;
                        UILabel *actionTitleLabel  = actionBtn.titleLabel;
                        CGFloat topMargin          = 14;
                        CGFloat bottomMargin       = topMargin;
                        CGFloat imageWH            = 18;
                        CGFloat labelX             = CGRectGetMinX(actionTitleLabel.frame) + (CGRectGetWidth(actionTitleLabel.frame) - titleSize.width) * 0.5;
                        CGFloat labelY             = bottomMargin + imageWH;
                        CATextLayer *titleLayer    = [CATextLayer layer];
                        titleLayer.contentsScale   = 2;
                        titleLayer.frame           = CGRectMake(labelX, labelY, titleSize.width, titleSize.height);
                        titleLayer.string          = titleStr;
                        titleLayer.fontSize        = 12;
                        titleLayer.foregroundColor = [UIColor whiteColor].CGColor;
                        [actionBtn.layer addSublayer:titleLayer];
                        
                        // 添加图片
                        CGFloat imageX   = CGRectGetMinX(actionTitleLabel.frame) + (CGRectGetWidth(actionTitleLabel.frame) - imageWH) * 0.5;
                        CGFloat imageY   = topMargin;
                        CGRect imageRect = CGRectMake(imageX, imageY, imageWH, imageWH);
                        
                        UIImage *image = nil;
                        if ([titleStr isEqualToString:@"删除"]) {
                            
                            image = [UIImage imageNamed:@"delete_icon"];
                        }
                        if ([titleStr isEqualToString:@"发送"]) {
                            
                            image = [UIImage imageNamed:@"send_icon"];
                        }
                        CALayer *layer = [CALayer layer];
                        layer.frame    = imageRect;
                        layer.contents = (id)image.CGImage;
                        [actionBtn.layer addSublayer:layer];
                        
                        // 移除系统文字
                        [actionTitleLabel removeFromSuperview];
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:iOS tableView坑集

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