我试图理解为什么我在单元格中为我的单元格中的不同标签设置的约束没有完成。这很重要,因为我的身高是动态的。
过去两天我遇到了这个问题,这让我感到困扰。不,UITableViewAutomaticDimension
不是我想要的。
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var cell = self.feed.dequeueReusableCellWithIdentifier("post") as PostCell
var post = self.posts[indexPath.row]
cell.name.text = post.name
cell.timestamp.text = post.timestamp
cell.postBody.text = post.body
println("\(cell.name.constraints())")
println("\(cell.postBody.constraints())")
cell.contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
cell.setNeedsUpdateConstraints()
cell.updateConstraintsIfNeeded()
cell.bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(feed.bounds), CGRectGetHeight(cell.bounds))
cell.setNeedsLayout()
cell.layoutIfNeeded()
var height = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize).height
height += 1.0
return height
}
当我打印为cell.postBody
设置的约束时,我得到[]
。但是,我有5个约束。 Superview的尾随空间,Superview的空间,Superview Equals 4的底部空间,2个不同标签的2个顶部空间等于8。
如果我的代码无法通过Storyboard查看约束,我该如何以编程方式设置这5个约束
我正在更新的方式:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = self.feed.dequeueReusableCellWithIdentifier("post") as PostCell
var post = self.posts[indexPath.row]
cell.name.text = post.name
cell.timestamp.text = post.timestamp
cell.postBody.text = post.body
if cachedHeights[post.id] == nil && cell.bounds.height != 0.0 {
cachedHeights[post.id] = cell.bounds.height
}
return cell
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var post = posts[indexPath.row]
if cachedHeights[post.id] != nil {
return cachedHeights[post.id]!
} else {
return 70
}
}
问题是,我不确定cell.bounds.height是否完全准确。我的意思是,我认为它有时使用前一个大单元格的高度(也许是从新单元出列的单元格。)
答案 0 :(得分:1)
标签上没有约束条件。这就是他们的constraints
属性返回空数组的原因。
您会在标签上找到约束条件。 superview,cell.contentsView
。
您可以跳过对setNeedsUpdateConstraints
和updateConstraintsIfNeeded
的来电,因为layoutSubviews会调用updateConstraintsIfNeeded
。
在切换到自行调整大小单元之前使用的旧方法:
我没有任何快速的代码,但是在切换到自行调整大小的单元之前,这里有来自应用程序的一些旧代码。它(隐式地)使用故事板单元格中标签上的约束。我唯一不同的就是缓存尺寸单元。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
static LeftDetailTableViewCell *cell;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
});
// configure the cell for this indexPath
[self configureCell:cell atIndexPath:indexPath];
// Set the sizing cell's width to the tableview's width
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
// get the fitting size
CGSize s = [cell.contentView systemLayoutSizeFittingSize: UILayoutFittingCompressedSize];
return s.height + 1.0;
}
<强>更新强>
这是我现在使用的代码,适用于iOS 8中的自定义单元格。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BIBLETableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
[cell adjustSizeToMatchWidth:CGRectGetWidth(self.tableView.frame)];
[self configureAccessoryTypeForCell:cell forRowAtIndexPath:indexPath];
[cell adjustConstraintsToMatchSeparatorInset:self.tableView.separatorInset];
[self configureCell:cell forRowAtIndexPath:indexPath];
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
return cell;
}
我的子类细胞有:
- (void)adjustSizeToMatchWidth:(CGFloat)width
{
// Workaround for visible cells not laid out properly since their layout was
// based on a different (initial) width from the tableView.
CGRect rect = self.frame;
rect.size.width = width;
self.frame = rect;
// Workaround for initial cell height less than auto layout required height.
rect = self.contentView.bounds;
rect.size.height = 99999.0;
rect.size.width = 99999.0;
self.contentView.bounds = rect;
}
- (void)adjustConstraintsToMatchSeparatorInset:(UIEdgeInsets)inset
{
if (self.leadingMargins)
{
for (NSLayoutConstraint *constraint in self.leadingMargins)
{
constraint.constant = inset.left;
}
}
if (self.trailingMargins)
{
for (NSLayoutConstraint *constraint in self.trailingMargins)
{
constraint.constant = self.accessoryType == UITableViewCellAccessoryDisclosureIndicator ? 0.0f : inset.left;
}
}
}