美文网首页iOS开发
UITableView - 整理下API

UITableView - 整理下API

作者: 居然是村长 | 来源:发表于2016-03-17 22:24 被阅读477次

    平时用的也就几个属性和几个方法,但是API又臭又长,今天整理一下。

    一般使用

    // 1 先创建tableView
        _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
        /*
         typedef NS_ENUM(NSInteger, UITableViewStyle) {
         UITableViewStylePlain,          // 平铺式(补充:有section时,自动悬浮在顶部) 
         UITableViewStyleGrouped         // 分段式
         };
         */
        _tableView.delegate = self;
        _tableView.dataSource = self;
        
        // 设置 默认高度,对应有高度估算,但是一般用第三方,高度缓存比较好用。
        _tableView.rowHeight = 60;// 也可以在 代理中设置,高度固定的话推荐这里设置。
    
    
    // 注册使用的 cell类,自己写的也一样
        [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])];
    
    // 2 实现必要的几个代理与数据源
    // 必须 
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 3;// 每段数量,一般结合数组使用
    }
    
    // 必须 cell初始化
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // 已注册的使用下面一行代码即可,不需要判断 !cell
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UITableViewCell class])];
    
        cell.textLabel.text = [NSString stringWithFormat:@"%zi",indexPath.row];
        // more setting
    
        return cell;
    }
    
    // 可选 分段数量
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 5;// 分段式特有,默认为1 。
    }
    
    // 可选 cell 高度,对应一个 估算高度
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return 66;
    }
    
    // 事件 已选中 与 已反选中
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        // do 这个比较多,下面基本没怎么用过 
    }
    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
        // do
    }
    
    // 别忘了,简单粗暴的 更新数据源
        [_tableView reloadData];
    

    到这里,tableView 基本使用过关。再加上自定义cell 的话,基本上的页面也差不多都能画个草图了(不考虑细节)

    额外属性

        // 分割线设置
        _tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;// 分割线
        _tableView.separatorColor = [UIColor redColor];
        _tableView.separatorInset = UIEdgeInsetsMake(0, 44, 0, 0);
        
        // iOS8 分割线 毛玻璃效果
        UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
        UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
        _tableView.separatorEffect = vibrancyEffect;
        
        // iOS9 根据内容调整宽度,不设置可能会出现iOS9 cell显示异常
        _tableView.cellLayoutMarginsFollowReadableWidth = NO;
        
    
        _tableView.allowsSelection = YES;// cell 是否可以选择
        _tableView.allowsSelectionDuringEditing = YES;// 编辑模式是否可以选择 cell
        _tableView.allowsMultipleSelection = YES;// 是否可以多
        _tableView.allowsMultipleSelectionDuringEditing = YES;// 编辑模式是否可以多选(YES 是会使默认的 删除和插入编辑模式失效)
    
    
    

    添加额外的 View - head/foot/background

    • tableView 本身的 background
        // 背景,一般设置后,需要设置cell 透明(cell.contentView 与 cell 本身),展示这个背景
         UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        // do custom:
        _tableView.backgroundView = backgroundView;
    
    • tableView 本身的 tableHead / tableFoot
    // 一个tableView  就一对,是跟随表上下移动,与section 的不一样!
        UIView *tableHeadView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
        // do custom,使用自动布局的话,建议在tableHeadView 铺底的基础上addSubView:(直接加可能会异常)
        _tableView.tableHeaderView = tableHeadView;
            
        UIView *tableFootView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 66)];
          // do custom
        _tableView.tableFooterView = tableFootView;
    
    • section 的 head / foot
    // 系统默认,可以设置高度
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
        return @"header";
    }
    - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
        return @"footer";
    }
    
    // 自定义
    // 与cell 同理注册(同时注册了head/foot)
        [_tableView registerClass:[UIView class] forHeaderFooterViewReuseIdentifier:NSStringFromClass([UIView class])];
    // 默认高度:每个section 一样,不一样用代理设置
        _tableView.sectionHeaderHeight = 40;
        _tableView.sectionFooterHeight = 40;
        
    
    // 代理
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
        return 40;
    }
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
        return 40;
    }
    
    // 设置 headView 和FootView 会使上面title 和 height 失效。
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
        UIView *headView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
        headView.backgroundColor = [UIColor yellowColor];
        return headView;
    }
    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
        UIView *footView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
        footView.backgroundColor = [UIColor orangeColor];
        return footView;
    }
    
    
    

    高亮 选中 与 滚动

    • 高亮代理
    - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
        return YES;
    }
    - (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
        NSLog(@"%zi",indexPath.row);
    }
    - (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
        
    }
    
    • 2 设置选中
    //
        [_tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:1] animated:YES scrollPosition:UITableViewScrollPositionTop];
        /*
         typedef NS_ENUM(NSInteger, UITableViewScrollPosition) {
         UITableViewScrollPositionNone,
         UITableViewScrollPositionTop,
         UITableViewScrollPositionMiddle,
         UITableViewScrollPositionBottom
         };// 选中cell 滚动到的位置
         */
        [_tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:1] animated:YES];
        
    
    • 3 设置滚动
        [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:2] atScrollPosition:UITableViewScrollPositionTop animated:YES];
        [_tableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionTop animated:YES];
        
    

    增删改移

    • 必须结构
      关键是对应修改数据源
        [tableView beginUpdates];
        // 使用 增删改移(之前必须先修改对应的数据源,可以在begin 之前)
        [tableView endUpdates];
    
        [tableView beginUpdates];
        
        [self.tableSource insertObject:@"test" atIndex:3];
        [tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
        /*
         typedef NS_ENUM(NSInteger, UITableViewRowAnimation) {
         UITableViewRowAnimationFade,
         UITableViewRowAnimationRight,           // slide in from right (or out to right)
         UITableViewRowAnimationLeft,
         UITableViewRowAnimationTop,
         UITableViewRowAnimationBottom,
         UITableViewRowAnimationNone,            // available in iOS 3.0
         UITableViewRowAnimationMiddle,          // available in iOS 3.2.  attempts to keep cell centered in the space it will/did occupy
         UITableViewRowAnimationAutomatic = 100  // available in iOS 5.0.  chooses an appropriate animation style for you
         }; // 过渡动画效果
         */
        
        [tableView endUpdates];
    
    //
        [tableView beginUpdates];
        
        [self.tableSource removeObjectAtIndex:3];
        [tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
        
        [tableView endUpdates];
    
    //
        [tableView beginUpdates];
        
        [self.tableSource replaceObjectAtIndex:3 withObject:@"replace"];
        [tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
     
        [tableView endUpdates];
    
    //
        [tableView beginUpdates];
        
        [self.tableSource exchangeObjectAtIndex:2 withObjectAtIndex:3];
        [tableView moveRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0] toIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
        
        [tableView 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);
    
    

    编辑 - 就是插入 与 删除 - 系统提供样式

    • 默认模式 - 删除 插入
    // 是否可以编辑
    - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
        return YES;
    }
    
    // 编辑方式 插入 和 删除
    - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
        return UITableViewCellEditingStyleDelete;
        /*
         typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) {
         UITableViewCellEditingStyleNone,(移动专用)
         UITableViewCellEditingStyleDelete,(删除专用)
         UITableViewCellEditingStyleInsert(插入专用)
         };
         */
    }
    
    // 是否缩进,(设置NO 是为了下面移动使用)这里必须YES
    - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
        return YES;
    }
    
    // 删除样式的时候,显示的提示
    - (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED {
        return @"雅蠛蝶";
    }
    
    // iOS8 
    //- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED {
    //    return @[];
    //}
    
    // 将要
    - (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
        // do
    }
    
    // 完成
    - (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath {
        // do
    }
    
    // 触发事件
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
        // 点击事件,1:默认删除,需要点击左滑出现的删除才触发。2:插入,点击+即触发 
    
    // 根据实际 情况删除 或者 插入,上面讲过了
        [tableView beginUpdates];
        [self.tableSource removeObjectAtIndex:indexPath.row];
        [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];    
        [tableView endUpdates];
        
    }
    
    • 编辑 之 多选
        _tableView.allowsMultipleSelectionDuringEditing = YES;// 编辑模式是否可以多选(YES 是会使上面默认的 删除和插入编辑模式失效)
    
    // 单选时 选中的行
        NSIndexPath *singleSelect = self.tableView.indexPathForSelectedRow;
    
    // 多选时选中的行s,
        NSArray *selects = self.tableView.indexPathsForSelectedRows;
        
    // to do 根据 上面的 NSIndexPath 可以进行相应的 删除等操作。
    

    编辑 之 移动

    
    - (UITableViewCellEditingStyle )tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
        return UITableViewCellEditingStyleNone;
    }
    - (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
        return NO;
    }
    
    - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
        return YES;
    }
    - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
        // cell 位置 移动了,但是数据源没变,需要手动调整
        [self.tableSource exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];
        NSLog(@"%@",self.tableSource[sourceIndexPath.row]);
        NSLog(@"%@",self.tableSource[destinationIndexPath.row]);
        NSLog(@"%@",self.tableSource);
    }
    

    索引

    
        _tableView.sectionIndexMinimumDisplayRowCount = 12;// 索引相关
        _tableView.sectionIndexColor = [UIColor redColor]; // 索引字颜色
        _tableView.sectionIndexBackgroundColor = [UIColor yellowColor];// normal 背景色
        _tableView.sectionIndexTrackingBackgroundColor = [UIColor blueColor];// highlighted 背景色
        [_tableView reloadSectionIndexTitles];
            
    
    // 索引内容
    - (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView {
        return @[@"0",@"1",@"2",@"3",@"4",@"5",@"6"];// 自己写
        return UITableViewIndexSearch;// 默认 section 第一个
    }
    
    // 点击索引 返回滚动 section 位置
    - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index __TVOS_PROHIBITED {
        NSLog(@"索引内容:%@ - 索引index:%zi",title,index);
        // do
        return index;
    }
    

    复制粘贴

    直接举例

    
    // 是否 显示 菜单
    - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
        return YES;
    }
    
    // 显示哪些 操作
    - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender {
    
        if (action == @selector(cut:)){
            return YES;
            
        } else if(action == @selector(copy:)){
            return YES;
            
        } else if(action == @selector(paste:)){
            return YES;
            
        } else if(action == @selector(select:)){
            return NO;
            
        } else if(action == @selector(selectAll:)){
            return NO;
            
        } else  {
            return NO;
        }
    }
    
    // 点击 回调 对应操作
    - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender {
        
        if (action ==@selector(copy:)) {
            [UIPasteboard  generalPasteboard].string = self.tableSource[indexPath.row];
        }
        
        if (action ==@selector(cut:)) {
            
            [UIPasteboard  generalPasteboard].string = self.tableSource[indexPath.row];
            
            [self.tableSource  replaceObjectAtIndex:indexPath.row withObject:@""];
            
            [tableView beginUpdates];
            [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationNone];
            [tableView endUpdates];
        }
        
        if (action ==@selector(paste:)) {
            
            NSString *pasteString = [UIPasteboard  generalPasteboard].string;
            
            [self.tableSource   replaceObjectAtIndex:indexPath.row withObject:pasteString];
            
            [tableView beginUpdates];
            [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationNone];
            [tableView endUpdates];
        }
        
    }
    

    展示相关 - 再设置犀利自定义时用的比较多

    例如,section headView 将要消失时,顶在最上面不消失,反之亦然。

    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
    - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
    - (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
    - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath NS_AVAILABLE_IOS(6_0);
    - (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
    - (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
    // 实际代码,不太好举例。
    

    获取信息

    //  UITableView.h 200-218 行,不写了
    

    其他

    // 修改选中/反选项 不是很常用
    - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        return [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section];
    }
    - (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
        return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section + 1];
    }
    
    // 缩进级别 不是像素
    - (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
        return 12;
    }
    
    
    
    
    

    待补充

    // iOS9 属性
    @property (nonatomic) BOOL remembersLastFocusedIndexPath NS_AVAILABLE_IOS(9_0); 
    @property (nonatomic, strong, readonly, nullable) NSIndexPath *previouslyFocusedIndexPath;
    @property (nonatomic, strong, readonly, nullable) NSIndexPath *nextFocusedIndexPath;
     
    // iOS9 代理
    - (BOOL)tableView:(UITableView *)tableView canFocusRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
    - (BOOL)tableView:(UITableView *)tableView shouldUpdateFocusInContext:(UITableViewFocusUpdateContext *)context NS_AVAILABLE_IOS(9_0);
    - (void)tableView:(UITableView *)tableView didUpdateFocusInContext:(UITableViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator NS_AVAILABLE_IOS(9_0);
    - (nullable NSIndexPath *)indexPathForPreferredFocusedViewInTableView:(UITableView *)tableView NS_AVAILABLE_IOS(9_0);
    
     
    // 其他代理
    - (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;               
    - (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath NS_DEPRECATED_IOS(2_0, 3_0) __TVOS_PROHIBITED;
    - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath;
    
    // iOS 8 
    typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) {
        UITableViewRowActionStyleDefault = 0,
        UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,
        UITableViewRowActionStyleNormal
    } NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;
    
    NS_CLASS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED @interface UITableViewRowAction : NSObject <NSCopying>
    
    + (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(nullable NSString *)title handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler;
    
    @property (nonatomic, readonly) UITableViewRowActionStyle style;
    @property (nonatomic, copy, nullable) NSString *title;
    @property (nonatomic, copy, nullable) UIColor *backgroundColor; // default background color is dependent on style
    @property (nonatomic, copy, nullable) UIVisualEffect* backgroundEffect;
    @end
    
    
    // 其他
    UIKIT_EXTERN NSString *const UITableViewIndexSearch NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
    UIKIT_EXTERN const CGFloat UITableViewAutomaticDimension NS_AVAILABLE_IOS(5_0);
    UIKIT_EXTERN NSString *const UITableViewSelectionDidChangeNotification;
    

    1

    相关文章

      网友评论

        本文标题:UITableView - 整理下API

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