UICollectionView 单元格子视图不调整大小
Posted
技术标签:
【中文标题】UICollectionView 单元格子视图不调整大小【英文标题】:UICollectionView cell subviews do not resize 【发布时间】:2013-02-24 12:50:18 【问题描述】:在CollectionView
中,一些单元格应该有一个额外的子视图或层。可以告诉CollectionView
调整其单元格的大小,因此所有内容都需要适当地调整大小。
目前,该单元格是从一个包含带有 imageview 的单元格的 nib 初始化的;单元格笔尖链接到自定义 UICollectionViewCell
子类,该子类仅执行 init。 Autoresize 子视图被选中。
CollectionView
被告知通过在sizeForItemAtIndexPath:
中派生和返回的值来调整单元格的大小。我对 FlowLayout 进行了子类化,但它只指定了 ScrollDirection
和 Insets
。
所有这些都运行良好。问题:如何将子视图/图层添加到单元格,以便它也正确调整大小?我尝试在关闭translatesAutoresizingMaskIntoConstraints
的情况下添加子视图和图层,但它们根本不会自动更改大小。还尝试使用代码框架/视图而不是笔尖。
我现在得到的最好的是一个cell.contentView.layer
子层,我在cellForItemAtIndexPath:
中添加了它;这是通过存储来自sizeForItemAtIndexPath:
的单元格的frame.size
来“手动”调整大小的,这不仅丑陋,而且最终导致子层对于不同的单元格具有不同的大小。
任何帮助表示赞赏!
【问题讨论】:
使用自动布局,如果约束设置正确,子视图应自动随单元格展开。您需要描述此子视图,以及如果您需要更具体的帮助,您希望它如何扩展。 感谢@rdelmar 的评论。我对约束有一种模糊的感觉,但从未跟进,所以我没有想到只是将它们关闭。做到了,它的工作原理......现在我只需要处理应该很容易的起源。谢谢! 【参考方案1】:我遇到了同样的问题。在两种布局之间切换并没有调整单元格内的图片(UIImage)大小。我的细胞在没有 xib 的情况下构建。我为每个 CollectionViewCustomLayout 使用了两个不同的单元格类。
我以编程方式解决了这个问题:
self.autoresizesSubviews = YES;
在我的 UICollectionViewCell 子类中。
但这仅对我有用,方法是将图片添加为单元格背景图片,如下所示:
cell.backgroundView[[UIImageView alloc] initWithImage: SumDummyImage ];
【讨论】:
【参考方案2】:我正在以编程方式添加 subView 和约束,以下代码适用于我:
lazy var imageView: UIImageView = [unowned self] in
let imageView = UIImageView(frame: self.contentView.frame)
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
()
func updateCellWith(image: UIImage)
contentView.subviews.forEach $0.removeFromSuperview()
contentView.addSubview(imageView)
imageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
imageView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0).isActive = true
imageView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0).isActive = true
imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true
self.imageView.autoresizingMask.insert(.flexibleHeight)
self.imageView.autoresizingMask.insert(.flexibleWidth)
imageView.image = image
【讨论】:
【参考方案3】:根据this article,@Alfie Hanssen 解决方案 (here) 不适用于我:
XIB 中单元格视图的大小为 50 x 50 磅,这是流布局中设置的集合视图单元格的默认大小。即使在 Interface Builder 中使用这么小的单元格有点困难,最好不要更改默认大小。问题是 Auto Layout 认为手动设置的大小是固定的,并在尝试自动调整单元格高度时生成 NSAutoresizingMaskLayoutConstraint 错误
我检查了 UICollectionViewCell,发现单元格和 contentView 之间有一个视图,并且该视图具有固有的宽度和高度约束。而不是 AutoresizingMask 我只是更新如下,似乎对我有用。
override func layoutSubviews()
contentView.superview?.frame = bounds
super.layoutSubviews()
【讨论】:
【参考方案4】:*override func awakeFromNib()
super.awakeFromNib()
self.contentView.autoresizingMask.insert(.FlexibleHeight)
self.contentView.autoresizingMask.insert(.FlexibleWidth)
这对我有用.. 此代码位于您的子类 UICollectionViewCell.swift 文件中(涉及自定义单元格的代码所在的位置)
快速解决方案*
【讨论】:
我怎么会忘记这个...谢谢!【参考方案5】:作为启用 AutoResizingMask 的替代方法,对于具有可变高度的自定义 UICollectionViewLayouts,例如您手动设置一些约束并且需要 translatesAutoresizingMaskIntoConstraints 保持 NO,您可以将以下内容添加到单元格中的 layoutSubviews:
self.contentView.frame = self.bounds;
这可以解决我在 Xcode 6 中出现问题的所有自定义集合视图布局。
【讨论】:
+1 这对我有用,但真的不需要多余的CGRectInset
【参考方案6】:
我刚才遇到了同样的问题。
当使用 UICollectionViewFlowLayoutDelegate 方法根据设备和设备方向设置单元格大小时,将正确计算大小,但子视图不会调整大小以填充新大小的单元格。效果是一个带有小子视图的大空白单元格,这些子视图不填充单元格的边界/保持大小等于它们在 xib 文件中的当前值。
我通过在awakeFromNib
中执行以下操作解决了这个问题:
- (void)awakeFromNib
[super awakeFromNib];
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.contentView.translatesAutoresizingMaskIntoConstraints = YES;
在执行此操作之前,contentView 掩码为nil
。
【讨论】:
感谢@alfie-hanssen,您的解决方案有助于解决使用自定义 UICollectionViewLayout 从 Xcode5 切换到 Xcode6 时出现的错误 谢谢,很高兴它有帮助! 谢谢。一旦我开始使用 Xcode 6 GM 构建,这个问题就出现在 ios 7 设备上,并将它添加到我的所有集合单元子类中修复了它。 谢谢你,阿尔菲!当我开始使用 XCode 6 GM 构建时,iOS 7 设备也存在同样的问题。 这里是同一问题的另一个答案的链接:***.com/a/25768887/2631081【参考方案7】:一个简单的自动布局解决方案是为容器视图设置约束。
因此,如果我们有一个带有父视图的图像视图,我们基本上希望告诉子视图(图像视图)与容器视图保持 0 的前导、尾随、底部和顶部空间距离。
【讨论】:
【参考方案8】:如果可能,我总是更喜欢自动布局。 但有时,当视图仅由其父视图直接确定时,使用框架和边界会节省时间。
在 UICollectionViewCell 的情况下,我将图像设置为单元格框架 +
self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
但是当我在 collectionView 中有不同大小的单元格时,它会搞砸事情,并且图像有时会占用不同单元格的大小。
所以我转而使用细胞边界,并且 - 确实效果很好。
那么不妨试试看?
【讨论】:
【参考方案9】:在另一个没有 xibs 的项目中,我将 UICollectionViewCell 子类化并为相同的效果这样做:
#import "CVcell.h"
@implementation CVcell
@synthesize cellImage;
- (id)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
CGFloat cellSize = self.contentView.bounds.size.width;
cellImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, cellSize, cellSize)];
[cellImage setClipsToBounds:YES];
cellImage.translatesAutoresizingMaskIntoConstraints = NO;
cellImage.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.contentView addSubview:cellImage];
return self;
@end
【讨论】:
不将translatesAutoresizingMaskIntoConstraints
设置为NO 意味着它将忽略autoresizingMask
?我的印象是,在非自动布局中没有这样的东西,只有模仿旧/替代方式的自动布局。【参考方案10】:
解决方案是关闭单元格 xib 的 AutoConstraints,并在图像视图的 AutoResize 中激活灵活的宽度/高度箭头。
【讨论】:
关闭约束会导致 xib 文件子视图错位以上是关于UICollectionView 单元格子视图不调整大小的主要内容,如果未能解决你的问题,请参考以下文章
当边界 UICollectionView 更改时调整单元格大小
配置 UICollectionView 以保持相同的单元格视图
UICollectionView 从另一个视图控制器返回时重复单元格