我想我偶然发现了UITableView类中的奇怪错误。如果来自表的单元格包含UItextView(在我的情况下不可编辑且不可滚动),并且用户选择其文本(显示复制菜单),则包含该特定UITextView的单元格将不再起作用。 UITableView不再为该单元格触发willDisplayCell和cellForRowAtIndexPath方法。我做了一些测试,当它们在屏幕外时,单元格从visibleCells数组中删除,当它们再次出现在屏幕上时,它们被放回到visibleCells数组中,但是没有调用委托方法。
这非常烦人,因为它会阻止您配置可重用的单元格。我不确定这是否被视为一个错误。我想如果你可以仔细检查并确认这种行为。
这是我的简化测试代码,因此您可以自行检查:
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
tableData = [[NSArray alloc]initWithObjects:@"First Text",@"Second",@"Third",@"Fourth",@"5th",@"6th",@"7th",@"8th",@"9th",@"10th",@"11th",@"12th",@"13th", nil];
self.tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStylePlain];
self.tableView.backgroundColor = [UIColor darkGrayColor];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.view addSubview:self.tableView];
UIButton* btn = [[UIButton alloc]initWithFrame:CGRectMake(200, 0, 100, 30)];
[btn setBackgroundColor:[UIColor redColor]];
[btn setTitle:@"Clickme" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark - TableView Datasource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return tableData.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UITextView* tv = [[UITextView alloc]initWithFrame:cell.contentView.bounds];
[tv setEditable:NO];
[cell.contentView addSubview:tv];
}
for (UIView* subview in cell.contentView.subviews)
{
if([subview isKindOfClass:[UITextView class]])
{
UITextView* tv = (UITextView*)subview;
tv.text = [tableData objectAtIndex:indexPath.row];
}
}
NSLog(@"Configured cell at index: %d", indexPath.row);
return cell;
}
#pragma mark - TableView Delegate
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Will display cell at index: %d", indexPath.row);
}
#pragma mark - Button callback handlers
-(void)onBtnClick:(id)sender
{
NSLog(@"Number of visible cells: %d",[self.tableView visibleCells].count);
}
通过运行此代码,您可以看到在第一个单元格中选择文本将导致tableview在单元格再次出现在屏幕上时停止触发委托事件。通过按下按钮,您可以检查可见单元格的数量是否始终正确,这意味着正在添加单元格并将其移除到可见单元格列表中。它只是未被解雇的回调代理。
答案 0 :(得分:1)
不完全是一个解决方案,但另一种方法是继承UITableViewCell
并覆盖- (void)prepareForReuse
以便在重用之前进行任何清理。
答案 1 :(得分:0)
我可以在这里重现你的问题 - 一旦上下文菜单打开(复制,...),该单元格似乎保持焦点而不会重新加载。
如果您不需要UITextView的上下文菜单,可以使用硬编码的包装类来处理文本视图:
@interface NonSelectableTextView : UITextView
@end
@implementation NonSelectableTextView
-(BOOL)canBecomeFirstResponder {
return NO;
}
@end