繁体   English   中英

使用“自动布局”更新集合视图高度以适合表视图单元格中的所有单元格

[英]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.

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