UITableView详解

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *dataArray;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];


    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
    _tableView.dataSource = self;
    _tableView.delegate = self;
    [self.view addSubview:_tableView];

    // 设置行、段头、段尾高度
    _tableView.rowHeight = 44;
    // UITableViewStyleGrouped模式默认会有Section高度 直接修改sectionHeaderHeight的方式是不行的 需在代理方法中修改
    _tableView.sectionHeaderHeight = 20;
    _tableView.sectionFooterHeight = 20;

    // 估算高度 (默认0 表示没有估算高度)
    _tableView.estimatedRowHeight = 0;
    _tableView.estimatedSectionHeaderHeight = 0;
    _tableView.estimatedSectionFooterHeight = 0;

    // 设置背景视图
    _tableView.backgroundView = [UIView new];
    _tableView.backgroundColor = [UIColor clearColor];

    // 整表刷新
    [_tableView reloadData];
    // 刷新索引
    [_tableView reloadSectionIndexTitles];

    // 在编辑模式之外能否被选中 默认YES
    _tableView.allowsSelection = YES;

    // 设置cell分隔线位置
    _tableView.separatorInset = UIEdgeInsetsZero;
    // 设置每行之间的分割线颜色
    _tableView.separatorColor = [UIColor blueColor];
    // 设置行线样式
    _tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    /*
     UITableViewCellSeparatorStyleNone              无行线
     UITableViewCellSeparatorStyleSingleLine        默认
     UITableViewCellSeparatorStyleSingleLineEtched  此样式仅支持分组模式的tableView
     */

    // 进入编辑模式
    [_tableView setEditing:YES animated:YES];

    // 多行选取模式
    // 默认为NO,当此值为YES时,UITableView进入编辑模式 不会向dataSource查询editStyle,而会直接每个Cell的左边显示圆形选择框,点击选择该行后圆形框里面为对勾。可使用 indexPathsForSelectedRows方法获取到所有选择行的indexPath。
    _tableView.allowsMultipleSelectionDuringEditing = YES;
    // 注:当allowsMultipleSelectionDuringEditing属性为YES时,不管当前在不在编辑模式内,swipe to delete都不起作用,若要同时使用滑动删除,需在完成选择任务后,将tableView的allowsMultipleSelectionDuringEditing恢复为NO。另外,“多选”控件不会与“插入”控 件,”删除”控件同时出现,却可以和”重排序”控件同时存在。保证UITableViewCell的selectionStyle属性不为UITableViewCellSelectionStyleNone,否则选择后的“红勾”无法显示。
    // 获取选择的所有行时,可以使用私有方法indexPathsForSelectedRows获取


    // 跳转指定行或段
    [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
    /*
     UITableViewScrollPositionNone      指定行滚动到刚好显示位置
     UITableViewScrollPositionTop       指定行滚动到表头部
     UITableViewScrollPositionMiddle    指定行滚动到表中部
     UITableViewScrollPositionBottom    指定行滚动到表底部
     */
}

#pragma mark - UITableView DataSource

// 返回有多少个Section 不实现此方法则默认为1
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}
// 返回有多少个Row
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 10;
}

// 设置cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString * showUserInfoCellIdentifier = @"ShowUserInfoCell";
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:showUserInfoCellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:showUserInfoCellIdentifier];
    }
    /*
     UITableViewCellStyleDefault        左侧显示textLabel(不显示detailTextLabel),imageView可选(显示在最左边)
     UITableViewCellStyleValue1         左侧显示textLabel、右侧显示detailTextLabel(默认蓝色),imageView可选(显示在最左边)
     UITableViewCellStyleValue2         左侧依次显示textLabel(默认蓝色)和detailTextLabel,imageView可选(显示在最左边)
     UITableViewCellStyleSubtitle       左上方显示textLabel,左下方显示detailTextLabel(默认灰色),imageView可选(显示在最左边)
     */

    // 设置cell背景颜色 默认nil
    cell.contentView.backgroundColor = [UIColor clearColor];
    // 设置标题
    cell.textLabel.text = @"签名";
    // 设置副标题
    cell.detailTextLabel.text = @"xxx";
    // 设置最左侧视图
    cell.imageView.image = [UIImage imageNamed:@"imageName"];               // 未选cell时的图片
    cell.imageView.highlightedImage = [UIImage imageNamed:@"imageName"];    // 选中cell后的图片

    // 设置附件视图的风格(cell最右侧显示的视图)
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    /*
     UITableViewCellAccessoryNone                       不显示任何图标(默认)
     UITableViewCellAccessoryDisclosureIndicator        跳转指示图标(箭头)
     UITableViewCellAccessoryDetailDisclosureButton     内容详情图标和跳转指示图标
     UITableViewCellAccessoryCheckmark                  勾选图标
     UITableViewCellAccessoryDetailButton               内容详情图标
     */
    // 自定义附件视图 设置后忽视accessoryType
    cell.accessoryView = [UIView new];
    // 编辑时自定义附件视图 设置后忽视editingAccessoryType
    cell.editingAccessoryView = [UIView new];

    // cell选中时的颜色状态 默认UITableViewCellSelectionStyleBlue
    cell.selectionStyle = UITableViewCellSelectionStyleBlue;
    // cell编辑时的颜色状态 默认UITableViewCellAccessoryNone
    cell.editingAccessoryType = UITableViewCellAccessoryNone;
    /*
     UITableViewCellSelectionStyleNone      选中时没有颜色效果
     UITableViewCellSelectionStyleBlue      选中时蓝色效果
     UITableViewCellSelectionStyleGray      选中时灰色效果
     UITableViewCellSelectionStyleDefault   选中时默认灰色效果
     */

    UIView *selectedView = [[UIView alloc] initWithFrame:cell.contentView.frame];
    selectedView.backgroundColor = [UIColor orangeColor];
    // 选中状态下的背景视图
    cell.selectedBackgroundView = selectedView;
    // 多选选中时的背景视图
    cell.multipleSelectionBackgroundView = selectedView;

    // 设置分割线的偏移量
    cell.separatorInset = UIEdgeInsetsZero;

    // 设置编辑状态下是否显示缩进 默认YES
    cell.shouldIndentWhileEditing = YES;
    // 设置内容区域的缩进级别 默认0
    cell.indentationLevel = 0;
    // 设置每个级别的缩进宽度 默认10.0
    cell.indentationWidth = 10.0;

    // 设置是否编辑模式
    cell.editing = YES;
    [cell setEditing:YES animated:YES];

    // 设置cell是否选中状态
    cell.selected = YES;
    [cell setSelected:YES animated:YES];
    // 设置cell是否高亮状态
    cell.highlighted = YES;
    [cell setHighlighted:YES animated:YES];

    // cell状态将要转换时调用的函数,可以在子类中重写
    [cell willTransitionToState:UITableViewCellStateDefaultMask];
    // cell状态已经转换时调用的函数,可以在子类中重写
    [cell didTransitionToState:UITableViewCellStateShowingEditControlMask];
    /*
     UITableViewCellStateDefaultMask                    默认状态
     UITableViewCellStateShowingEditControlMask         编辑状态
     UITableViewCellStateShowingDeleteConfirmationMask  确认删除状态
     */

    // 是否显示排序控件 默认NO
    cell.showsReorderControl = NO;
    //为了使UITableVeiew进入edit模式以后,如果该cell支持reordering的话,reordering控件就会临时的把accessaryView覆盖掉。为了显示reordering控件,我们必须将cell的showsReorderControl属性设置成YES,同时实现dataSource中的tableView:moveRowAtIndexPath:toIndexPath:方法。我们还可以同时通过实现dataSource中的 tableView:canMoveRowAtIndexPath:返回NO,来禁用某一些cell的reordering功能。


    // 删除按钮是否显示 readonly
    BOOL isShowDeleteButton = cell.showingDeleteConfirmation;
    // 获取cell标示符
    NSString *reuseIdentifier = cell.reuseIdentifier;

    // iOS9新属性
    cell.focusStyle = UITableViewCellFocusStyleDefault;
    /*
     UITableViewCellFocusStyleDefault 
     UITableViewCellFocusStyleCustom
     */

    return cell;
}

// 当被重用的cell将要显示时,会调用下面这个方法,这个方法最大的用武之地是当你自定义的cell上面有图片时,如果产生了重用,图片可能会错乱(当图片来自异步下载时及其明显),这时我们可以重写这个方法把内容抹掉。
//- (void)prepareForReuse;


// 返回指定的 section 的 header 的 title,如果这个section header 有返回view,那么title就不起作用
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return @"HeaderTitle";
}

// 返回指定的 section 的 footer 的 title,如果这个section footer 有返回view,那么title就不起作用
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
    return @"FooterTitle";
}

#pragma mark - 索引
// 设置表右边索引
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    tableView.sectionIndexColor = [UIColor blackColor]; // 字体颜色
    tableView.sectionIndexBackgroundColor = [UIColor clearColor]; // 背景色
    // 返回要是一个内容为NSString 的NSArray 里面存放section title
    // 默认情况下 section Title根据顺序对应 section 【如果不写tableView: sectionForSectionIndexTitle: atIndex:的话】
    return [NSArray new];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    // 通过传入的传入每个sectionIndex的title,index 来设置这个sectionIndex 对应的section
    // 一般不需要写 默认section index 顺序与section对应。除非 你的section index数量或者序列与section不同才用修改
    return 0;
}

#pragma mark - 插入和删除
// 1.进入编辑模式后,UITableView向其DataSource发送tableView:canEditRowAtIndexPath:消息询问每个indexPath是否可编辑
// 2.然后,UITableView 向其delegate发送tableView:editingStyleForRowAtIndexPath:消息询问EditingStyle,这里返回删除(UITableViewCellEditingStyleDelete)或者插入(UITableViewCellEditingStyleInsert)
// 3.当点击”Delete”按钮或者”加号”按钮时,UITableView向其DataSource发送tableView:commitEditingStyle:forRowAtIndexPath:消息,根据传递editingStyle来执行实际的删除或插入操作

// 设置行能否编辑 默认YES
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 在此方法中对不可以编辑的cell返回NO,可以编辑的cell返回YES,若全部可编辑,可不实现,大部分应用不实现此方法。
    if (indexPath.row == 1) {
        return NO;
    }
    return YES;
}

// 添加和删除的数据操作 根据cell的编辑模式,在点击行的添加或删除按钮后,在下面的方法中更新数据源
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 先修改tableView的数据模型,向其中删除或插入对应数据项,然后再调整tableView的显示,删除或插入对应的cell
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [_dataArray removeObjectAtIndex:indexPath.row];
        // 动态删除UITableView 的UITableViewCell的操作
        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
        [tableView endUpdates];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        [_dataArray insertObject:@"new Item" atIndex:indexPath.row];
        [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
    //tableView insertSections:<#(nonnull NSIndexSet *)#> withRowAnimation:<#(UITableViewRowAnimation)#>
    //tableView deleteSections:<#(nonnull NSIndexSet *)#> withRowAnimation:<#(UITableViewRowAnimation)#>
    //tableView moveSection:<#(NSInteger)#> toSection:<#(NSInteger)#>
}

/*
 UITableViewRowAnimationFade            淡入淡出
 UITableViewRowAnimationRight           从右滑入
 UITableViewRowAnimationLeft            从左滑入
 UITableViewRowAnimationTop             从上滑入
 UITableViewRowAnimationBottom          从下滑入
 UITableViewRowAnimationNone            无
 UITableViewRowAnimationMiddle          从中间滑入
 UITableViewRowAnimationAutomatic       自动选择合适的动画
 */

#pragma mark - 重排序

// 若当前tableView允许重排序,则会在每个cell的右侧出现三条灰色横线的控件,拖动此空间可将cell移动到不同的位置。重排序模式和删除/插入是并行的,即可在显示重排序空间的同时显示删除或插入控件。
// 设置cell能否重排 需要把单元格的编辑属性设置为YES,[tableView setEditing:YES animated:YES];
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    /*
     UITableViewCellEditingStyleNone        不可编辑
     UITableViewCellEditingStyleDelete      删除 Cell左侧会显示红色”减号”按钮 点击后减号会旋转90度变竖形,并且cell右侧出现”Delete”按钮
     UITableViewCellEditingStyleInsert      添加 cell左侧会显示绿色”加号”按钮
     */
    // 若不实现此方法,则默认为删除模式,即UITableViewCellEditingStyleDelete
    return UITableViewCellEditingStyleNone;
}
// 自定义delete按钮标题
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"删除";
}
// 1.tableView向其DataSource发送tableView:canMoveRowAtIndexPath:消息,询问每一行是否可显示重排序控件(三条横线),若为NO,则不显示,若为YES则显示。此方法不实现时默认所有行都可显示重排序控件。这时就会在每一行的右侧显示重排序控件。因为重排序没有使用向delegate发送tableView:editingStyleForRowAtIndexPath:消息询问编辑模式,所以其 与删除、插入控件可同时存在,在一般情况下不应该同时出现,所以应实现了 tableView:editingStyleForRowAtIndexPath:并返回 UITableViewCellEditingStyleNone;若不实现 tableView:editingStyleForRowAtIndexPath:则会默认使用删除模式,即右侧出现“排序”控件时,左侧会出现”删 除”控件。
// 2.用户可拖动每行右侧的重排序控件来移动该行的位置
// 3.用户拖动某行经过目标行上方时,tableView会向delegate发送tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:(若delegate有实现)消息询问是否可移动到此位置(ProposedIndexPath),若不可移动到此位置则返回一个新的目的indexPath,可以的话直接将ProposedIndexPath返回即可。一般情况下不需实现此方法
// 4.当用户放手时本次重排序操作结束,调用dataSource中的tableView:moveRowAtIndexPath:toIndexPath:方法更新tableView对应的数据。
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    // 需要的移动行
    NSInteger fromRow = [sourceIndexPath row];
    // 获取移动某处的位置
    NSInteger toRow = [destinationIndexPath row];
    // 从数组中读取需要移动行的数据
    id object = [_dataArray objectAtIndex:fromRow];
    // 在数组中移动需要移动的行的数据
    [_dataArray removeObjectAtIndex:fromRow];
    // 把需要移动的单元格数据在数组中,移动到想要移动的数据前面
    [_dataArray insertObject:object atIndex:toRow];
}
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    NSLog(@"targetIndexPathForMoveFromRowAtIndexPath");
    //用于限制只在当前section下面才可以移动
    if(sourceIndexPath.section != proposedDestinationIndexPath.section) {
        return sourceIndexPath;
    }
    return proposedDestinationIndexPath;
}

#pragma mark -
#pragma mark - UITableView Delegate

// 自定义段头视图
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return [UIView new];
}

// 自定义段尾视图
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    return [UIView new];
}

#pragma mark - row、section高度

// 返回指定 section 的 header view 的高度 (实现这个代理方法后前面 sectionHeaderHeight 设定的高度无效)
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 44;
}

// 返回指定 section 的 footer view 的高度 (实现这个代理方法后前面 sectionFooterHeight 设定的高度无效)
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 44;
}

// 返回指定 row 的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44;
}

// 用估算高度方法可以快速的计算表最后加载时的估算值
// 如果下面的方法被实现,上面的-tableView:heightForXXX方法被调用将被推迟直到视图即将显示,因此更多的逻辑推理可以被放置在这里
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 44;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section
{
    return 44;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section
{
    return 44;
}

#pragma mark - cell显示、高亮、选中、编辑、缩进状态

// cell处于被编辑状态时是否应该缩进  若未实现则所有cell处于编辑状态时都会缩进
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
// 设置内容区域的缩进级别
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 0;
}

// cell、header、footer显示回调
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"willDisplayCell");
}
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    NSLog(@"willDisplayHeaderView");
}
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section
{
    NSLog(@"willDisplayFooterView");
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath
{
    NSLog(@"didEndDisplayingCell");
}
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section
{
    NSLog(@"didEndDisplayingHeaderView");
}
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section
{
    NSLog(@"didEndDisplayingFooterView");
}

// 能否高亮
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
// 高亮状态时
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"didHighlightRowAtIndexPath");
}
// 取消高亮状态时
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"didUnhighlightRowAtIndexPath");
}

// 将要开始编辑时
- (void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"willBeginEditingRowAtIndexPath");
}
// 已经结束编辑时
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"didEndEditingRowAtIndexPath");
}

// 将要选中时
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"willSelectRowAtIndexPath");
    NSLog(@"当前选中的行是  \n indexpath = %@",indexPath);
    return indexPath;
}
// 将要取消选中时
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"willDeselectRowAtIndexPath");
    NSLog(@"上次选中的行是  \n indexpath = %@",indexPath);
    return indexPath;
}

// 选中时
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"didSelectRowAtIndexPath");
    UITableViewCell *cellView = [tableView cellForRowAtIndexPath:indexPath];
    if (cellView.accessoryType == UITableViewCellAccessoryNone) {
        cellView.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cellView.accessoryType = UITableViewCellAccessoryNone;
        [tableView deselectRowAtIndexPath:indexPath animated:YES]; // 选中后的反显颜色即刻消失
    }
}
// 取消选中时
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"didDeselectRowAtIndexPath");
}

// 点击cell最右侧视图的回调方法(如果有设置)
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"accessoryButtonTappedForRowWithIndexPath");
}


#pragma mark - 剪切、粘贴、复制

// 设置cell能否弹出Menu菜单 剪切、粘贴、复制
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
// 设置cell点击出现Menu菜单的action
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender
{
    return YES;  // 全部显示
    // 只显示copy
//    if (action == @selector(cut:)) {
//        return NO;
//    } else if (action == @selector(copy:)) {
//        return YES;
//    } else if (action == @selector(paste:)) {
//        return NO;
//    } else if (action == @selector(select:)) {
//        return NO;
//    } else if (action == @selector(selectAll:)) {
//        return NO;
//    } else {
//        return [super canPerformAction:action withSender:sender];
//    }
}
// 设置点击响应事件
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender
{
    if (action ==@selector(copy:)) {
        [UIPasteboard  generalPasteboard].string = [_dataArray objectAtIndex:indexPath.row];
    }

    if (action ==@selector(cut:)) {
        [UIPasteboard generalPasteboard].string = [_dataArray objectAtIndex:indexPath.row];
        [_dataArray replaceObjectAtIndex:indexPath.row withObject:@""];
        [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
    }

    if (action ==@selector(paste:)) {
        NSString *pasteString = [UIPasteboard generalPasteboard].string;
        NSString *tmpString = [NSString stringWithFormat:@"%@%@", [_dataArray objectAtIndex:indexPath.row], pasteString];
        [_dataArray replaceObjectAtIndex:indexPath.row withObject:tmpString];
        [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
    }
}

#pragma mark - iOS8 在滑动手势删除某一行时,显示更多的按钮
// 在滑动手势删除某一行时,显示更多的按钮
- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 通过UITableViewRowAction类来创建按钮
    // 可以设置按钮样式,显示的文字,背景色和按钮的事件(事件在block中实现)
    // 最先放入数组的按钮显示在最右侧,依次
    // 设定一个或多个按钮后,系统自带的删除按钮消失

    // 添加一个删除按钮
    UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        NSLog(@"点击了删除");
        [_dataArray removeObjectAtIndex:indexPath.row];
        // 动态删除UITableView 的UITableViewCell的操作
        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
        [tableView endUpdates];
    }];

    // 添加一个置顶按钮
    UITableViewRowAction *topRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"置顶" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        NSLog(@"点击了置顶");
        [_dataArray exchangeObjectAtIndex:indexPath.row withObjectAtIndex:0];
        NSIndexPath *firstIndexPath = [NSIndexPath indexPathForRow:0 inSection:indexPath.section];
        [tableView moveRowAtIndexPath:indexPath toIndexPath:firstIndexPath];
    }];
    topRowAction.backgroundColor = [UIColor blueColor];

    // 添加一个更多按钮
    UITableViewRowAction *moreRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"更多" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
        NSLog(@"点击了更多");
        [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationMiddle];
    }];
    moreRowAction.backgroundEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];


    return @[deleteRowAction, topRowAction, moreRowAction];
}

#pragma mark - 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);

@end

参考:http://blog.sina.com.cn/s/blog_51a995b70101iwgx.html
http://www.cnblogs.com/smileEvday/archive/2012/06/28/tableView.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值