(十九)TableView的点击监听和数据刷新(Alert的多种样式) -tag传值的技巧

要实现监听,要使用代理,控制器要成为TableView的代理。

注意下面的方式是代理方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"选中了第%d组的第%d行",indexPath.section,indexPath.row);
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"取消选中了第%d组的第%d行",indexPath.section,indexPath.row);
}

对于AlertView,有alertViewStyle属性来设置样式:

typedef NS_ENUM(NSInteger, UIAlertViewStyle) {
    UIAlertViewStyleDefault = 0,
    UIAlertViewStyleSecureTextInput,
    UIAlertViewStylePlainTextInput,
    UIAlertViewStyleLoginAndPasswordInput
};

PlainTextInput是有一个输入框的对话框。

这次的目的是点击TableView一项会弹出对话框可以修改点击的标题。

首先要监听AlertView。

刷新表格数据的步骤:1.修改模型数据 2.重新加载模型数据。

一个细节:两个方法之间传值的方法,因为TableView的点击事件触发了AlertView,此时是可以得到indexPath的,但是当AlertView被点击触发委托函数时,无法得到indexPath,这种传值不宜用全局变量,可以通过AlertView的tag来传递这个值

自动刷新数据:tableView的对象方法reloadData,会重新调用一遍各个方法,获得组、行和具体的cell。

具体过程:

1.遵循UIAlertViewDelegate的protocol:

@interface ViewController () <UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate>

2.在TableView的选中方法中常见AlertView,并设定委托为自身,注意修改alert的样式,注意其中的细节:用tag传递indexPath.row

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
    Hero *hero = self.heros[indexPath.row];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"数据展示" message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
    
    alert.alertViewStyle = UIAlertViewStylePlainTextInput;
    UITextField *textField = [alert textFieldAtIndex:0];
    textField.text = hero.name;
    
    alert.tag = indexPath.row;
    
    [alert show];
}
3.实现alertView的监听方法来修改数据:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    //点击了取消
    if (buttonIndex == 0) return;
    
    //点击了确定
    NSString *msg = [alertView textFieldAtIndex:0].text;
    
    Hero *hero = self.heros[alertView.tag];
    hero.name = msg;
    
    [self.tableview reloadData];
    
}

一个问题:reloadData刷新会将视野内的所有cell全部刷新,造成了内存浪费,这个用于刷新内容多的时候。

可以使用局部刷新来解决这个问题:只重新加载选中的cell。

局部刷新还可以使用动画:

NSIndexPath *path = [NSIndexPath indexPathForRow:alertView.tag inSection:0];
[self.tableview reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationBottom];

注意要传入刷新的组的数组的IndexPath,事先创建一个indexPath再传入,后面的值还可以设定动画。


为什么不直接改cell:因为cell的数据来自模型,模型不改,cell再次刷新还会变回模型的数据。


原文地址:https://www.cnblogs.com/aiwz/p/6154234.html