Ios 调整UICollectionViewCells的大小以始终填充UICollectionView
我有一个水平滚动的UICollectionView,其中UICollectionViewCells与collection视图本身一样高,三分之一宽(一次三个)。集合视图被分页并使用默认的流布局 这些单元格来自.xib文件,并使用自动布局将内容保留在适当的位置 我试图做的是让集合视图的高度在两个预定义高度之间切换,并让单元格的高度始终填充可用空间,即使在动画期间也是如此 集合视图动画是通过将顶部约束设置为其superview的动画来完成的,如下所示:Ios 调整UICollectionViewCells的大小以始终填充UICollectionView,ios,animation,uicollectionview,uicollectionviewcell,Ios,Animation,Uicollectionview,Uicollectionviewcell,我有一个水平滚动的UICollectionView,其中UICollectionViewCells与collection视图本身一样高,三分之一宽(一次三个)。集合视图被分页并使用默认的流布局 这些单元格来自.xib文件,并使用自动布局将内容保留在适当的位置 我试图做的是让集合视图的高度在两个预定义高度之间切换,并让单元格的高度始终填充可用空间,即使在动画期间也是如此 集合视图动画是通过将顶部约束设置为其superview的动画来完成的,如下所示: UIView.animateWithDurat
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.collectionViewTopConstraint.constant = (self.collectionViewTopConstraint.constant == 50 ? 100 : 50)
self.view.layoutIfNeeded()
})
然而,这使细胞保持不变
我已尝试在动画块末尾添加以下内容:
self.collectionView.performBatchUpdates({ () -> Void in
}, completion: nil)
这几乎是可行的,但是细胞从一个高度交叉衰减到另一个高度,而不是仅仅改变高度,这看起来很糟糕
我还尝试了以下方法:
self.collectionView.collectionViewLayout.invalidateLayout()
这可以达到相同的效果,但不是很平滑
此外,在这两种情况下,如果反复调用切换动画,我会收到以下警告:
the behavior of the UICollectionViewFlowLayout is not defined because:
the item height must be less than the height of the UICollectionView minus the section insets top and bottom values.
我做了大量的研究,但我发现的一切都涉及到自定义布局或在不同布局之间切换,我认为这不适用于我,因为即使集合视图的高度发生变化,布局也使用相同的逻辑来定位元素
有什么想法吗
谢谢 我认为这可以通过在动画之前更改单元格的itemSize来实现。单元格的原始大小设置为如下所示的相同值,但没有+符号*50项
- (IBAction)toggleCollectionViewSize:(id)sender {
self.collectionViewTopConstraint.constant = (self.collectionViewTopConstraint.constant == 50)? 100 : 50;
NSInteger sign = (self.collectionViewTopConstraint.constant == 50)? 1 : -1;
self.layout.itemSize = CGSizeMake(self.collectionView.frame.size.width/3.0 , self.collectionView.frame.size.height + sign*50);
[UIView animateWithDuration:.5 animations:^{
[self.view layoutIfNeeded];
}];
}
我在一个顶部、中部和底部都有视图的单元上测试了这个。看起来不错,但底部视图有轻微的移动,我无法解释。当转换发生时,您仍然会看到单元格的轻微褪色(其alpha值降低)。如果集合视图背景色与单元格背景色相同,则可以最小化此视觉效果
编辑后:
如果使用计时器而不是动画持续时间,效果会更好;这样我就不会褪色了
-(void)viewWillLayoutSubviews {
self.layout.itemSize = CGSizeMake(self.collectionView.bounds.size.width/3.0 , self.collectionView.bounds.size.height - 1); // the -1 suppresses a warning about the height that you get on every toggle. I still get one warning at the start.
}
- (IBAction)toggleCollectionViewSize:(id)sender {
NSInteger sign = (self.topCon.constant == 50)? 1 : -1;
[NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(shrink:) userInfo:@(sign) repeats:YES];
}
-(void)shrink:(NSTimer *) aTimer {
NSInteger sign = [aTimer.userInfo integerValue];
self.topCon.constant += sign;
if (self.topCon.constant == 100 || self.topCon.constant == 50) {
[aTimer invalidate];
}
}
谢谢这确实有效,但正如你所说,它并不完美,因为褪色仍然存在。我想知道使用自定义布局是否会改变这一点。我想我在某个地方读到过,淡入淡出是流量布局特有的东西…@LorTush,我想我找到了一种更好的使用计时器的方法。谢谢,我会尝试一下。我还将把它标记为正确答案,因为我认为这是我们在不使用自定义布局的情况下所能做的最好的选择。高度动画完成后,您可以调用collectionView.reload()。