我需要显示一堆具有不同高度的collectionViewCell.视图太复杂,我不想手动计算预期的高度.我想强制执行自动布局来计算单元格高度
dequeueReusableCellWithReuseIdentifier在cellForItemAtIndexPathbreak 之外调用collectionView并导致它崩溃
另一个问题是单元格不在单独的xib中,因此我无法手动实例化临时单元并将其用于高度计算.
对此有何解决方案?
public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
var cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellIdentifier, forIndexPath: indexPath) as UICollectionViewCell
configureCell(cell, item: items[indexPath.row])
cell.contentView.setNeedsLayout()
cell.contentView.layoutIfNeeded()
return cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
}
Run Code Online (Sandbox Code Playgroud)
编辑:
一旦调用dequeueReusableCellWithReuseIdentifier,就会发生崩溃.如果我不调用该方法而是返回一个大小,一切都很好,单元格显示没有计算的大小
流布局中不支持负值或零大小
2015-01-26 18:24:34.231 [13383:9752256] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
0 CoreFoundation 0x00000001095aef35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000109243bb7 objc_exception_throw + 45 …Run Code Online (Sandbox Code Playgroud) 这是导致警告的代码:
private override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
let distance = CGRectGetMidX(attributes!.frame) - self.midX;
var transform = CATransform3DIdentity;
transform = CATransform3DTranslate(transform, -distance, 0, -self.width);
attributes!.transform3D = CATransform3DIdentity;
return attributes
}
Run Code Online (Sandbox Code Playgroud)
控制台还打印:
这可能是因为流布局"xyz"正在修改UICollectionViewFlowLayout返回的属性而不复制它们.
我该如何修复此警告?
(编辑:从iOS 9开始看起来工作正常.我没有进行大量测试,但是这个例子很有效.这证实了iOS 8中存在的错误.)
我花了很多时间测试UICollectionView的Flow Layout自我调整大小的行为.经过很多挫折之后,问题被缩小到这样一个事实:只要将其设置为estimatedItemSize非零大小,滚动就不再正常工作.
在我的示例中,它不显示40个项目,而只显示32个项目.
我复制粘贴下面的代码.我已经测试了许多以Swift版本开头的东西.
基本上它无法计算和/或正确更新布局 collectionViewContentSize()
这是一个完整的演示http://git.io/AIrHNA
有谁能指出我正确的方向?
谢谢
@implementation ViewControllerObjcC
static NSString * const reuseIdentifier = @"Cell";
-(UICollectionViewFlowLayout*)flowLayout{
return (UICollectionViewFlowLayout*)self.collectionViewLayout;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
CGSize estimatedSize = CGSizeMake(self.view.frame.size.width, 25.0);
BOOL testEstimatedItemSize = true;
if (testEstimatedItemSize) {
[self flowLayout].estimatedItemSize = estimatedSize;
}else{
[self flowLayout].itemSize = estimatedSize;
}
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 40;
}
- …Run Code Online (Sandbox Code Playgroud) iphone objective-c ios uicollectionview uicollectionviewlayout
我一直在玩弄动态UICollectionViewCell的和已经注意到,在iOS 8调用cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)上UICollectionViewCell返回不正确的宽度.目前解决此问题的唯一解决方法是显式添加宽度约束以强制单元格的宽度.以下代码用于Cell子类:
func calculatePreferredHeightForFrame(frame: CGRect) -> CGFloat {
var newFrame = frame
self.frame = newFrame
let widthConstraint = NSLayoutConstraint(item: contentView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: CGRectGetWidth(frame))
contentView.addConstraint(widthConstraint)
self.setNeedsUpdateConstraints()
self.updateConstraintsIfNeeded()
self.setNeedsLayout()
self.layoutIfNeeded()
let desiredHeight: CGFloat = self.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
newFrame.size.height = CGFloat(ceilf(Float(desiredHeight)))
contentView.removeConstraint(widthConstraint)
return CGRectGetHeight(newFrame)
}
Run Code Online (Sandbox Code Playgroud)
我知道,对于iOS 8和动态UICollectionViewFlowLayout,UICollectionViewCell的contentView以不同的方式处理约束,但是我在这里缺少什么?为确保systemLayoutSizeFittingSize在单元格上使用特定宽度,需要做些什么?
我也遇到过这篇文章(使用自动布局在UICollectionView中指定单元格的一个维度)并且相信这可能实际上使我的问题无效.也许UICollectionViewFlowLayout不是为只有一个动态维度的单元格设计的,但仍然无法解释为什么单元格给出了不寻常的宽度.