(十九)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再次刷新还会变回模型的数据。