[英]Update collection view height to fit all cells within a table view cell using Auto Layout
我想利用iOS 8中动态的UITableViewCell
高度。我需要在UITableViewCell
放置一个UICollectionView
。 我想确保集合视图中的所有单元格都在屏幕上可见,因此表格单元格的高度应该增加以适合集合视图。 我几乎有这个工作。 我只是无法使表格单元格大小合适 - 它的长度太长或太短,并且在我与表格交互之前可以看到一些布局问题(下面有更多内容)。
我已经将集合视图的自动布局约束设置为表格单元格的contentView
:leading,trailing,top和bottom。 然后我在集合视图上创建了一个高度约束,这样我就可以在计算适当的高度后动态更新它的constant
,以适应集合视图中的所有单元格(因为我认为没有办法自动执行此操作)。
这是设置的其余部分。
viewDidLoad {
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 44
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let cellDimension = self.collectionView.frame.size.width / 7 //always 7 columns
let flowLayout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
flowLayout.itemSize = CGSizeMake(cellDimension, cellDimension)
self.collectionViewHeightConstraint.constant = cellDimension * 4 //always 4 rows
}
我还没有实现heightForRowAtIndexPath
。
此设置会导致冲突的垂直约束。 我已经尝试降低约束的优先级并在一堆组合中改变关系,但没有一个导致所需的行为。 如果我将高度约束的优先级降低到999,则表格视图单元格最初太高,但在我向上和向下滚动表格视图后,表格单元格高度更新为预期高度。 对于其他一些组合,结果是表格单元格太短但整个集合视图渗出,表格单元格太短而集合视图被切断,或者表格单元格太高,基于什么优先级和我已经应用于约束的关系。 此外,在视图设置为动画时,集合视图单元格不会以适当的大小显示(但它们会在动画完成时正确调整),或者如果我重新加载表格,则集合视图单元格的大小不正确,直到我滚动桌子。
如何解决这些外观问题以获得动态表格视图单元格高度,其中包含基于显示宽度的动态单元格大小的完全可见的集合视图?
从我可以理解你的代码来设置collectionView单元格和大小,在我看来,你想要有方形的收集单元格,并有4行7个单元格,所有完全可见。
如果向单元格中的collectionView添加约束到所有4个边距(顶部,底部,左侧和右侧),然后将7:4的纵横比约束添加到collectionView,则tableview应该能够自动计算单元格高度为您提供合适的尺寸。
这是我如何处理这个问题,我认为它可以在IB中完成。
首先,我为CV单元设置了最小尺寸,然后我将CV的拥抱优先级设置为尽可能紧紧地拥抱其内容。 这应该保证,除了所有外部影响之外,CV将尝试具有使其所有细胞可见的最小可能尺寸。
接下来,我将使用TBV单元格的内容视图和CV播放相同的游戏,也就是说,我将TBV单元格内容视图的拥抱优先级设置为尽可能紧密地拥抱CV。 同样,这应该强调,忽略外部影响,TBV单元应保持其需要保持的最小尺寸,以便完整地显示CV。
看看forkingdog如何在这里解决了tableview单元动态高度的相同问题> https://github.com/forkingdog/UITableView-FDTemplateLayoutCell
你应该能够为uicollectionview切换出imageview。
在他的桌面视图中 - 而不是使用开箱即用的估计行高 - 你需要类似的东西
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [tableView fd_heightForCellWithIdentifier:@"FDFeedCell" configuration:^(FDFeedCell *cell) {
cell.entity = self.feedEntities[indexPath.row];
}];
}
#import "UITableView+FDTemplateLayoutCell.h"
#import <objc/runtime.h>
@implementation UITableView (FDTemplateLayoutCell)
- (id)fd_templateCellForReuseIdentifier:(NSString *)identifier;
{
NSAssert(identifier.length > 0, @"Expects a valid identifier - %@", identifier);
NSMutableDictionary *templateCellsByIdentifiers = objc_getAssociatedObject(self, _cmd);
if (!templateCellsByIdentifiers) {
templateCellsByIdentifiers = @{}.mutableCopy;
objc_setAssociatedObject(self, _cmd, templateCellsByIdentifiers, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
UITableViewCell *templateCell = templateCellsByIdentifiers[identifier];
if (!templateCell) {
templateCell = [self dequeueReusableCellWithIdentifier:identifier];
templateCellsByIdentifiers[identifier] = templateCell;
}
return templateCell;
}
- (CGFloat)fd_heightForCellWithIdentifier:(NSString *)identifier configuration:(void (^)(id))configuration
{
// Fetch a cached template cell for `identifier`.
UITableViewCell *cell = [self fd_templateCellForReuseIdentifier:identifier];
// Reset to initial height as first created, otherwise the cell's height wouldn't retract if it
// had larger height before it gets reused.
cell.contentView.bounds = CGRectMake(0, 0, CGRectGetWidth(self.frame), self.rowHeight);
// Manually calls to ensure consistent behavior with actual cells (that are displayed on screen).
[cell prepareForReuse];
// Customize and provide content for our template cell.
if (configuration) {
configuration(cell);
}
// Add a hard width constraint to make dynamic content views (like labels) expand vertically instead
// of growing horizontally, in a flow-layout manner.
NSLayoutConstraint *tempWidthConstraint =
[NSLayoutConstraint constraintWithItem:cell.contentView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:CGRectGetWidth(self.frame)];
[cell.contentView addConstraint:tempWidthConstraint];
// Auto layout does its math
CGSize fittingSize = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
[cell.contentView removeConstraint:tempWidthConstraint];
// Add 1px extra space for separator line if needed, simulating default UITableViewCell.
if (self.separatorStyle != UITableViewCellSeparatorStyleNone) {
fittingSize.height += 1.0 / [UIScreen mainScreen].scale;
}
return fittingSize.height;
}
@end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.