【问题标题】:UITableView willDisplayCell not fired when cell contains UITextView当单元格包含 UITextView 时,UITableView willDisplayCell 不会被触发
【发布时间】:2012-08-18 15:33:49
【问题描述】:

我想我偶然发现了 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 在单元格再次出现在屏幕上时停止触发委托事件。通过按下按钮,您可以检查可见单元格的数量是否始终正确,这意味着单元格正在被添加和删除到可见单元格列表中。只是没有触发的回调委托。

【问题讨论】:

    标签: objective-c ios uitableview uitextview


    【解决方案1】:

    不完全是一个解决方案,但一种替代方法是继承 UITableViewCell 并覆盖 - (void)prepareForReuse 以在重用之前进行任何清理。

    【讨论】:

      【解决方案2】:

      我可以在这里重现您的问题 - 一旦上下文菜单打开(复制,...),该单元格似乎保持焦点并且不会重新加载。

      如果你不需要 UITextView 的上下文菜单,你可以为你的文本视图使用硬编码的包装类:

      @interface NonSelectableTextView : UITextView
      
      @end
      
      @implementation NonSelectableTextView
      
      -(BOOL)canBecomeFirstResponder {
          return NO;
      }
      
      @end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-19
        • 2014-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多