我有一个UITableViewController,其中包含一些自定义单元格和每个单元格中的UIView。我已经实现了控制器的cellForRowAtIndexPath来配置每个单元格中的UIView。为此,我需要知道屏幕上UIView的宽度。由于我使用autolayout和size类来根据设备方向自动更改UIView的大小,因此我实现了另一种获取宽度运行时的方法。
问题在于,当第一次显示表视图时,即使我在横向使用设备时,我的代码也会从紧凑的宽度尺寸类报告UIVIew的宽度。系统渲染所有视图,但我的代码获取宽度不起作用。滚动新单元格可见或方向更改将立即解决问题。
我的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ...
CustomCell* cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
cell = [nib firstObject];
} else {
// Clear custom content
NSArray *viewsToRemove = [cell.histogramView subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
}
[cell setNeedsLayout];
[cell layoutIfNeeded];
int width = ((CustomView*)cell.customView).getWidth;
NSLog(@"width = %d", width);
// ...
}
然后:
@implementation CustomView
- (int)getWidth {
[self setNeedsLayout];
[self layoutIfNeeded];
int width = self.frame.size.width;
return width;
}
@end
编辑添加:
问题似乎是在第一次出现tableview时调用cellForRowAtIndexPath时,单元格没有发生autolayout。在创建单元格后立即使用[cell setNeedsLayout]和[cell layoutIfNeeded]强制它也不会起作用。
似乎我的问题根本原因是How to know the width of an UITableViewCell when using auto layout?的潜在重复因此问题与以下事实有关:当我的CustomCell从nib加载时,它将具有默认帧。应该采取特殊措施强制自动布局。但是,接受的答案不适用于最初超出可见区域的单元格。对此有何看法?
答案 0 :(得分:0)
我建议尝试使用约束和比率而不是框架的实际宽度,因为正如Marcus Adams所说,框架将具有您实际只在viewDidAppear之后寻找的值。
例如,如果您的单元格包含的单元格宽度为1/3的UILabel,以及填充剩余空间的UIImageView,则可以在它们与父视图之间设置约束。
你的逻辑可以像这样改变吗?
另一个建议是在viewDidAppear之后在你的表视图上调用reloadData,但这绝对不是一个很好的选择UX。
答案 1 :(得分:0)
我找到了正确的解决方案:
cell.contentMode = UIViewContentModeRedraw
tableview: cellForRowAtIndexPath:
为自定义单元格实现layoutSubviews
,如下所示:
- (void)layoutSubviews {
[super layoutSubviews];
NSLog(@"cell width == %f", self.bounds.size.width);
}
通过这种方式,您可以访问屏幕上显示的单元格大小。