简体   繁体   English

UIView纵横比混淆systemLayoutSizeFittingSize

[英]UIView aspect ratio confuses systemLayoutSizeFittingSize

Alright, another UITableViewCell dynamic height problem, but with a little twist. 好吧,另一个UITableViewCell动态高度问题,但有点扭曲。 Unfortunately I can't jump to iOS 8 only when released, otherwise the problem would be solved. 不幸的是,我只有在发布时才能跳转到iOS 8,否则问题就会解决。 Need iOS >= 7.1. 需要iOS> = 7.1。

I'm trying to achieve a cell with two images on the top of the cell, a title label below them and a description label below that. 我正在尝试在单元格的顶部创建一个包含两个图像的单元格,在它们下方有一个标题标签,下面是一个描述标签。 I know the two top images will be square and thus I want them to be of the same size and to keep the square aspect ratio but resize when the screen size varies (like orientation change or different device). 我知道两个顶部图像将是正方形,因此我希望它们具有相同的尺寸并保持方形纵横比,但在屏幕尺寸变化时调整大小(如方向更改或不同设备)。

An image that might help with the visualization (can't include because of rep. Nevermind the colors, visualization help): http://i.stack.imgur.com/kOhkl.png 可能有助于可视化的图像(由于代表无法包含颜色,可视化帮助): http//i.stack.imgur.com/kOhkl.png

Notice the gap after the last text, that's not supposed to be there. 注意最后一个文本之后的差距,那不应该在那里。

I implemented dynamic height in previous application according to: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights (with success), and used the same method now as well. 我根据以下应用程序在以前的应用程序中实现了动态高度: 在UITableView中使用自动布局进行动态单元格布局和可变行高度 (成功),并且现在也使用相同的方法。

I have setup the constraints using both storyboards and programmatically but with no success. 我已经使用故事板和编程方式设置了约束,但没有成功。

Here's the kicker though. 这是踢球者。 When calling: 致电时:

CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

In: 在:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

the height value is way bigger than the height when reading: 高度值大于读取时的高度:

cell.contentView.frame

Another issue is that if I remove the aspect ratio constraints on the images and only changes it to an explicit height constraint it works fine. 另一个问题是,如果我删除图像上的宽高比约束并仅将其更改为显式高度约束,则它可以正常工作。

For anyone willing to help I put together a really simple sample project illustrating the problem: https://github.com/alefr/DynamicTableCellHeight 对于任何愿意帮助的人,我都会组建一个非常简单的示例项目来说明问题: https//github.com/alefr/DynamicTableCellHeight

It's setup to use storyboards for constraints and there's an extra branch: ExplicitHeightConstraint that does nothing but change the aspect ration constraint to a height constraint for the images. 它设置为使用故事板进行约束,并且有一个额外的分支:ExplicitHeightConstraint,除了将纵横比限制更改为图像的高度约束之外什么都不做。

**So the question is: ** Can anyone see anything wrong with the constraints that makes it confuse the height calculations, or do anyone have any alternative suggestions to get the wanted result? **所以问题是:**任何人都可以看到使高度计算混淆的约束有任何问题,或者是否有人有任何其他建议来获得想要的结果? (Although I'd like to use auto layout for the views). (虽然我想为视图使用自动布局)。

There's quite a few constraints in the works (although nothing really fancy) so I think it's easier to look in the provided storyboard (github link) than stating them explicitly here. 在工作中有很多限制(虽然没有什么真正的花哨)所以我认为在提供的故事板(github链接)中查找比在这里明确说明它们更容易。 But if someone fancies that I can do that as well. 但如果有人幻想我也可以这样做。 The estimated height calculations look like: 估计的高度计算如下:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

// Don't care about memory leaks now:
DynamicTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"dynamicCell"];

[self populateCell:cell withContent:self.tableData[indexPath.row]];

// Make sure the constraints have been set up for this cell, since it may have just been created from scratch.
// Use the following lines, assuming you are setting up constraints from within the cell's updateConstraints method:
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];

// Set the width of the cell to match the width of the table view. This is important so that we'll get the
// correct cell height for different table view widths if the cell's height depends on its width (due to
// multi-line UILabels word wrapping, etc). We don't need to do this above in -[tableView:cellForRowAtIndexPath]
// because it happens automatically when the cell is used in the table view.
// Also note, the final width of the cell may not be the width of the table view in some cases, for example when a
// section index is displayed along the right side of the table view. You must account for the reduced cell width.
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));

// Do the layout pass on the cell, which will calculate the frames for all the views based on the constraints.
// (Note that you must set the preferredMaxLayoutWidth on multi-line UILabels inside the -[layoutSubviews] method
// of the UITableViewCell subclass, or do it manually at this point before the below 2 lines!)
[cell setNeedsLayout];
[cell layoutIfNeeded];

// Get the actual height required for the cell's contentView
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

// So we can read debug values
CGRect contentFrame = cell.contentView.frame;
CGRect firstImageFrame = cell.firstArtwork.frame;
CGRect secondImageFrame = cell.secondArtwork.frame;
CGRect nameFrame = cell.name.frame;
CGRect numArtworksFrame = cell.numArtworks.frame;

// Add an extra point to the height to account for the cell separator, which is added between the bottom
// of the cell's contentView and the bottom of the table view cell.
height += 1.0f;
return height;
}

- (void)populateCell:(DynamicTableViewCell*)cell withContent:(DynamicContent*)content
{
    cell.firstArtwork.image = content.firstImage;
    cell.secondArtwork.image = content.secondImage;
    cell.name.text = content.name;
    cell.numArtworks.text = [NSString stringWithFormat:@"%@ artworks", content.numImages];
}

Thanks 谢谢

I was in the same situation, and solved it to override the systemLayoutSizeFittingSize function in the given cell and replace the aspectRation constraint to a height constraint. 我处于相同的情况,并解决它以覆盖给定单元格中的systemLayoutSizeFittingSize函数,并将aspectRation约束替换为高度约束。 In the following example the mediaPlayerAspectRationConstraint is added to the view during the view lifecycle and the mediaPlayerHeightContraint is going to use to determine the right height of the cell (see the code below). 在以下示例中, mediaPlayerAspectRationConstraint在视图生命周期中添加到视图中, mediaPlayerHeightContraint将用于确定单元格的正确高度(请参阅下面的代码)。

So, I used the 所以,我用了

CGFloat height = [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

instead of the [cell.contentView systemLayoutSizeFittingSize:] . 而不是[cell.contentView systemLayoutSizeFittingSize:]

- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize {
    self.mediaPlayerHeightContraint.constant = CGRectGetHeight(self.experienceMedia.frame);

    //Lets replace it with an exact height constraint (workaround).

    //To remove the Unable to simultaneously satisfy constraints. exceptions
    [self.contentView layoutIfNeeded];

    [self.experienceMedia removeConstraint:self.mediaPlayerAspectRationConstraint];
    [self.experienceMedia addConstraint:self.mediaPlayerHeightContraint];

    [self setNeedsUpdateConstraints];

    CGSize res = [self.contentView systemLayoutSizeFittingSize:targetSize];

    [self.contentView layoutIfNeeded];

    [self.experienceMedia removeConstraint:self.mediaPlayerHeightContraint];
    [self.experienceMedia addConstraint:self.mediaPlayerAspectRationConstraint];

    [self setNeedsUpdateConstraints];

    return res;
}

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

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