简体   繁体   English

自定义UITableViewCell具有自动布局和附件视图

[英]Custom UITableViewCell with auto layout and accessory view

I have a custom table view cell that uses auto layout and has a disclosure indicator as an accessory view. 我有一个自定义表格视图单元格,它使用自动布局,并有一个披露指标作为附件视图。 The cell size of the cells on the screen are completely wrong when first displayed: 首次显示时,屏幕上单元格的单元格大小完全错误:

As you can see the cell is taking about a 1.5 screens worth of space: 正如您所看到的那样,该单元占用了大约1.5个屏幕的空间:

在此输入图像描述

However if I rotate the device and rotate back it looks fine: 但是,如果我旋转设备并向后旋转它看起来很好:

在此输入图像描述

As you can see here, I've done nothing complicated: 正如你在这里看到的,我没有做过任何复杂的事情:

在此输入图像描述

I have a very NON-IDEAL workaround which is to do: 我有一个非常非理想的解决方法:

-(void)viewDidAppear:(BOOL)animated 
{
    [super viewDidAppear:animated];
    [self.tableView reloadData];
}

But that obviously causes a 'flash' when you first see the screen. 但是当你第一次看到屏幕时,这显然会导致“闪光”。 In a more complicated scenario the flash is far more obvious. 在更复杂的情况下,闪光灯更加明显。

I have another workaround but this causes an auto layout exception: 我有另一个解决方法,但这会导致自动布局异常:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    BasicCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BasicCell" forIndexPath:indexPath];
    cell.basicLabel.text = @"Hello this is just some text that should get the label to go over multiple lines";
    [cell.basicLabel layoutIfNeeded];
    return cell;
}

Exception: 例外:

在此输入图像描述

At least this method doesn't give me UI flashing. 至少这种方法不会给我UI闪烁。

If I remove the accessory view it actually works perfectly fine. 如果我删除附件视图,它实际上完全正常。

UPDATE: I've added a sample project to github: https://github.com/fwaddle/TableCellAccessoryTest 更新:我已经向github添加了一个示例项目: https//github.com/fwaddle/TableCellAccessoryTest

UPDATE #2: Turns out another work around this bug is to layout the cell in code. 更新#2:关于这个错误的另一项工作是在代码中布局单元格。 I just tried doing the same thing in code and it didn't throw the warning and worked fine. 我只是尝试在代码中做同样的事情,它没有抛出警告并且工作正常。 Looks like an IB bug. 看起来像一个IB bug。

Any ideas how to work around this issue? 有任何想法如何解决这个问题? Thanks. 谢谢。

Implement the following delegate method as this solved the problem for me. 实现以下委托方法,因为这解决了我的问题。

- (void)tableView:(UITableView *)tableView   
willDisplayCell:(UITableViewCell *)cell 
forRowAtIndexPath:(NSIndexPath*)indexPath

A table view sends this message to its delegate just before it uses cell to draw a row, thereby permitting the delegate to customize the cell object before it is displayed. 表视图在使用单元格绘制行之前将此消息发送到其委托,从而允许委托在显示单元格对象之前对其进行自定义。 This method gives the delegate a chance to override state-based properties set earlier by the table view, such as selection and background color. 此方法为委托提供了覆盖表视图前面设置的基于状态的属性的机会,例如选择和背景颜色。 After the delegate returns, the table view sets only the alpha and frame properties, and then only when animating rows as they slide in or out. 委托返回后,表视图仅设置alpha和frame属性,然后仅在向行或向外滑动时为行设置动画。

Add this code to your tableViewController: 将此代码添加到tableViewController:

 - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell   forRowAtIndexPath:(NSIndexPath *)indexPath{

    BasicCell *basicCell = (BasicCell *)cell;
    basicCell.basicLabel.text = @"Hello this is just some text that should get the label to go over multiple lines";

}

So even creating the constraints in code sometimes doesn't fix this issue. 因此,即使在代码中创建约束,有时也无法解决此问题。 It seems you need a few more changes. 您似乎还需要进行一些更改。 In your custom table cell add the following especially if you're changing the accessory type depending on the contents of the cell (eg Checkmark): 在您的自定义表格单元格中添加以下内容,尤其是在您根据单元格的内容更改附件类型时(例如,选中标记):

-(void) setAccessoryType:(UITableViewCellAccessoryType)accessoryType {
  [super setAccessoryType:accessoryType];
  [self setNeedsUpdateConstraints];
}

Also remove the prototype cell in the storyboard and register your class instead: 同样删除故事板中的原型单元格并注册您的类:

-(void) viewDidLoad {
  [super viewDidLoad];
  [self.tableView registerClass:[MyCustomCell class] forCellReuseIdentifier:@"MyCustomCell"];
}

I occasionally find that I still need to force labels (especially multi-line labels it seems) to re layout in cellForRowAtIndexPath: 我偶尔会发现我仍然需要强制标签(特别是多行标签)在cellForRowAtIndexPath中重新布局:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCustomCell" forIndexPath:indexPath];
  cell.customLabel.text = .....
  [cell.customLabel layoutIfNeeded];
  return cell;
}

All of the above fixed my issues so I hope they're of use to others and you don't waste a large amount of time on this. 以上所有问题都解决了我的问题所以我希望它们对别人有用,而且你不会浪费大量时间。

I still haven't heard anything back from Apple about the bug report but I assume that's pretty normal. 我还没有听到苹果公司关于错误报告的任何回复,但我认为这很正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM