我想利用iOS 8中新的动态UITableViewCell
高度。我需要在UICollectionView
内放置UITableViewCell
。我想确保集合视图中的所有单元格都在屏幕上可见,因此表格单元格的高度应该增加以适合集合视图。我几乎有这个工作。我只是无法让表格单元格大小合适 - 它的长度太长或太短,并且在我与表格交互之前会看到一些布局问题(更多内容见下文)。
我已将集合视图的自动布局约束设置为表格的单元格contentView
:前导,尾随,顶部和底部。然后我在集合视图上创建了一个高度约束,这样我就可以在计算适当的高度后动态更新它的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,则表格视图单元格最初太高,但在我向上和向下滚动表格视图后,表格单元格高度更新为预期高度。对于其他一些组合,结果是表格单元格太短但整个集合视图渗出,表格单元格太短而集合视图被切断,或者表格单元格太高,基于什么优先级和我已经应用于约束的关系。此外,在视图设置为动画时,集合视图单元格不会以适当的大小显示(但它们会在动画完成时正确调整),或者如果我重新加载表格,则集合视图单元格的大小不正确,直到我滚动桌子。
如何解决这些外观问题以获取动态表格视图单元格高度,其中包含一个完全可见的集合视图,其中包含基于显示宽度的动态单元格大小?
答案 0 :(得分:1)
从设置collectionView单元格和大小的代码中我可以理解,在我看来,你想要有方形集合单元格,并且有4行7个单元格,并且全部可见。
如果向单元格中的collectionView添加约束到所有4个边距(顶部,底部,左侧和右侧),然后将7:4的Aspect Ratio Constraint添加到collectionView,则tableview应该能够计算正确尺寸的自动细胞高度。
答案 1 :(得分:0)
以下是我如何处理这个问题,我认为可以在IB中完成所有工作。
首先,我为CV单元设置了最小尺寸,然后我将CV的拥抱优先级设置为尽可能紧密地拥抱其内容。这应该保证,除了所有外部影响之外,CV将尝试尽可能小的尺寸使其所有细胞都可见。
接下来,我将使用TBV单元格的内容视图和CV播放相同的游戏,也就是说,我将TBV单元格内容视图的拥抱优先级设置为尽可能紧密地拥抱CV。同样,这应该强调,忽略外部影响,TBV单元应保持其需要保持的最小尺寸,以便完整地显示CV。
答案 2 :(得分:0)
看看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