iOS 8:UITableViewCell详细文本无法正确更新

aci*_*ris 18 objective-c uitableview viewwillappear ios autolayout

tl; dr:我可以让detailTextLabel通过iOS中的自动布局系统更新其大小吗?

自iOS 8以来,是否有其他人在UITableViewCell中遇到了detailText标签的问题?

我有一个表格,其中包含文字和细节字符串.最初的详细文本是一个空字符串(@"").在将故事板segue执行到编辑屏幕后,我返回一个新的详细文本值并更新它.我尝试在viewWillAppear中重新加载表,以便在返回上一个视图后立即显示该值.

表格视图再次可见后,表格单元格已将文本字段向上移动以为详细文本腾出空间,但不显示任何明细文本.在我返回编辑屏幕并再次返回之前,文本不会显示.

我做了什么来排除故障:看起来我认为细节文本标签的自动布局没有正确更新,并且记录detailTextLabel框架的大小和构成证实了这一点.

我可以通过在viewDidAppear中运行[table reloadData]来强制更新文本,但是这会让我感觉不到我喜欢的闪烁效果,并且看起来不专业.

编辑:我做过的其他事情:我还强迫detailTextLabel使用[cell.detailTextLabel sizeToFit]重新调整自身大小.这导致它显示,但在单元格中以奇数方式偏移.再次进入编辑页面后,detailTextLabel会修复它的位置.

我已经创建了一个简单的项目作为github repo,以准确显示我正在处理的内容:

https://github.com/acidaris/ios8_table_issue

我正在使用的视图控制器的主要代码也在下面.

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


- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section {
    return 1; 
}

- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];

    cell.textLabel.text = @"This is a test";
    cell.detailTextLabel.text = self.value;

    CGRect frame = cell.detailTextLabel.frame;
    NSLog(@"detailTextLabel x=%f y=%f width=%f height=%f",
        frame.origin.x,frame.origin.y,frame.size.width,frame.size.height);
    return cell; 
}
Run Code Online (Sandbox Code Playgroud)

该单元格在StoryBoard中进行原型化,因此始终定义由dequeueReusableCellWithIdentifier:选择的单元格.此外,故事板中的单元格类型设置为字幕,如果定义了初始值,它会显示.

如果有人能帮我解决这个问题,我将非常感激.

部分解决方案

如果要对UITableViewCell进行子类化,则可以在布局完成后修改detailTextLabel的框架.这就是我所做的,它似乎有效,但在6加上,我在textLabel和detailTextLabel之间得到了一个奇怪的分界线.编辑:(我已经调整了这个.)我不喜欢这个解决方案,但到目前为止,这是我遇到的最好的.它在呈现视图后不会更新,并且相对简单.如上所述,我将继续寻找更好的解决方案.

- (void)layoutSubviews {
  [super layoutSubviews]; 
  CGRect textFrame = self.textLabel.frame;
  [self.detailTextLabel sizeToFit];

  CGFloat x = textFrame.origin.x;
  CGFloat y = textFrame.origin.y + textFrame.size.height;

  CGSize detailSize = self.detailTextLabel.frame.size;
  CGRect newFrame = CGRectMake(x, y, detailSize.width, detailSize.height);

  self.detailTextLabel.frame = newFrame;
}
Run Code Online (Sandbox Code Playgroud)

我还更新了我的Github项目,以反映我目前的解决方案.编辑3:这不能很好地工作,因为它有真正的自动布局框架的错误值,但它适用于我的用途.

编辑4:我已将layoutSubviews功能更新为更智能.它将调整标签内容的大小,并将标签适当地放置在相对于文本标签的x/y坐标内.

小智 19

有同样的问题.我的解决方案是[cell layoutSubviews]在结束时返回单元格之前调用-tableView:cellFForRowAtIndexPath.这适用于我,我没有发现有必要layoutSubviews在细胞子类中重写.

  • 调用`[cell layoutIfNeeded]`解决问题并且对我来说非常有效.如果需要强制布局,只需要调用`setNeedsLayout`. (6认同)
  • 请**请勿直接调用layoutSubviews.如果需要立即更新单元格的布局,请调用setNeedsLayout,然后调用layoutIfNeeded. (2认同)

Odd*_*rne 8

在故事板中使用segue时,我有同样的问题,单元格没有正确更新.试着

[setNeedsLayout] and [layoutIfNeeded]
Run Code Online (Sandbox Code Playgroud)

在视图和tableview上,它不起作用.

[self.tableView reloadData] is in viewDidAppear, as it should.
Run Code Online (Sandbox Code Playgroud)

然后我尝试了pixbug的建议,它起作用了.但是不应该直接使用[layoutSubviews].所以我尝试了由单元格上的文档而不是tableView或视图提供建议的那些.

试着

[cell setNeedsLayout] 
Run Code Online (Sandbox Code Playgroud)

但这没用.

试着

[cell layoutIfNeeded] 
Run Code Online (Sandbox Code Playgroud)

这适合我.

我在退回牢房前把它放了.


Gil*_*and 0

我认为如果您需要重新加载数据,这意味着表数据在创建时不会加载。

您只需要在 tableview 所在的 viewdidload (或 table view 获取其数据之前的其他地方)加载数据,然后相应地创建单元格。

通常,我只是使用我正在使用的任何对象的数组,然后使用[array objectAtIndex:indexpath.row]你可能知道的。

另外,你的最后一段有一个未完成的句子,看起来很重要。