我有两个ViewControllers:
带有“推”按钮的UIViewController,另一个带有tableView的UIViewController。
PushAction
- (IBAction)pushViewController:(id)sender {
NSArray *dataArr = @[@1,@2,@3,@4,@5];
NextViewController *nextViewController = [[NextViewController alloc] init];
[nextViewController setDataAndReload:dataArr];
[self.navigationController pushViewController:nextViewController animated:YES];
}
NextViewController.h
@interface NextViewController : UIViewController
- (void)setDataAndReload:(NSArray *)dataArr;
@end
NextViewController.m
#import "NextViewController.h"
@interface NextViewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UITableView *tableView;
@end
@implementation NextViewController {
NSMutableArray *_arr;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView];
[self.tableView reloadData];
}
- (void)setDataAndReload:(NSArray *)dataArr {
//[self loadViewIfNeeded];
_arr = [dataArr mutableCopy];
[self.tableView reloadData];
}
#pragma mark - data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _arr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:@"Cell %@", _arr[indexPath.row]];
return cell;
}
#pragma mark - delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[_arr removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.backgroundColor = [UIColor whiteColor];
}
return _tableView;
}
您注意到我在将tableView添加到任何视图之前调用了[self.tableView reloadData]
然后,当我选择tableView上的任何单元格(选择后将调用[self.tableView reloadData]
)时,tableView不会按预期重新加载。
通过向tableView的dataSource方法添加一些断点进行调试后,我发现numberOfRowsInSection:
已被正确调用,但cellForRowAtIndexPath
已调用而不是。
然后我认为导致问题的原因可能是在我将tableView添加到viewController的视图之前setDataAndReload:
调用[self.tableView reloadData]
。所以我添加了[self loadViewIfNeeded]
并且cellForRowAtIndexPath:
被正确调用。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[_arr removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
因此,我想知道为什么在tableView的委托方法 cellForRowAtIndexPath
中[self.tableView reloadData]
之后无法调用didSelectRowAtIndexPath:
。
答案 0 :(得分:1)
我找到了cellForRowAtIndexPath
[self.tableView reloadData]
的原因
当我在[self.tableView reloadData]
中调用setDataAndReload:
时,它将调用tableView的惰性方法。
当我使用self.view.bounds
初始化表视图时,在第一次调用setDataAndReload:
时,视图尚未加载。所以它将加载如下(虽然tableView尚未创建并返回)
:
loadView
- &gt; viewDidLoad
- &gt; [self.view addSubview:self.tableView]
- &gt;懒惰的方法agian
- &GT;返回第二个tableView
- &GT; self.tableView
是第二个tableView
- &GT;第二个tableView被添加到superView
- &GT;返回第一个tableView
- &GT; self.tableView
是第一个tableView
因此,self.tableView
最终指向的tableView从未添加到superView!
答案 1 :(得分:0)
当你设置你的- (void)setDataAndReload:(NSArray *)dataArr
时,就像你悲伤一样,tableView
甚至没有被初始化,也不是视图层次结构的一部分。所以我建议将方法重命名为- (void)setData:(NSArray *)dataArr
并仅在viewDidLoad
重新加载tableView。
所以这是您更新的代码:
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView];
[self.tableView reloadData];
}
- (void)setDataAndReload:(NSArray *)dataArr {
_arr = [dataArr mutableCopy];
}
答案 2 :(得分:0)
在didSelectRowAtIndexPath
中,如果tableView没有重新加载数据。你应该检查调用者self.tableView
,它一定有问题。并且您会发现self.tableView
已将其指针更改为新的tableView
。然后你应该检查你的getter方法。在getter方法中,如果我们想要使用一些属性,我们必须要小心。因为有时我们可能不止一次调用getter,为什么?在您的示例中,您尝试从self.view
获取边界,self.view
将向-(void)loadView;
发送消息,这是VC的生命周期方法,-(void)loadView
将发送消息到-(void)viewDidLoad;
现在,-(void)viewDidLoad
再次呼叫self.tableView
。 Fortuantely,它不会导致循环。