根据Apple的留档(并在WWDC 2012上吹捧),可以在UICollectionView
上动态设置布局,甚至可以为更改设置动画:
通常在创建集合视图时指定布局对象,但是也可以动态更改集合视图的布局。layout对象存储在collectionViewLayout属性中。直接设置此属性会立即更新布局,而不会以动画形式显示更改。如果要以动画形式显示更改,必须改为调用setCollectionViewLayout:animated:方法。
然而,在实践中,我发现< code>UICollectionView对< code>contentOffset进行了莫名其妙甚至无效的更改,导致单元格移动不正确,使该功能实际上不可用。为了说明这个问题,我将下面的示例代码放在一起,这些代码可以附加到一个默认的集合视图控制器中,并放入一个故事板中:
#import <UIKit/UIKit.h>
@interface MyCollectionViewController : UICollectionViewController
@end
@implementation MyCollectionViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"CELL"];
self.collectionView.collectionViewLayout = [[UICollectionViewFlowLayout alloc] init];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"contentOffset=(%f, %f)", self.collectionView.contentOffset.x, self.collectionView.contentOffset.y);
[self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES];
NSLog(@"contentOffset=(%f, %f)", self.collectionView.contentOffset.x, self.collectionView.contentOffset.y);
}
@end
控制器在viewDidLoad
中设置默认UICollectionViewFlowLayout
并在屏幕上显示单个单元格。选择单元格后,控制器会创建另一个默认UICollectionViewFlowLayout
,并在集合视图上使用动画设置:YES
flag。预期的行为是单元格不移动。然而,实际的行为是单元格滚动出屏幕,此时甚至无法将单元格滚动回屏幕。
查看控制台日志会发现内容Offset莫名其妙地发生了变化(在我的项目中,从(0,0)到(0,205))。我发布了非动画案例的解决方案(即动画:NO
),但由于我需要动画,我非常想知道是否有人有动画案例的解决方案或解决方法。
顺便说一下,我已经测试了自定义布局,得到了相同的行为。
假设您的“汽车”视图有许多布局。
假设你有三个。
CarsLayout1: UICollectionViewLayout { ...
CarsLayout2: UICollectionViewLayout { ...
CarsLayout3: UICollectionViewLayout { ...
当你在布局之间动画时,它会跳。
这只是苹果犯下的一个不可否认的错误。毫无疑问,当您设置动画时,它会跳起来。
解决办法是这样的:
您必须具有全局浮点数,以及以下基类:
var avoidAppleMessupCarsLayouts: CGPoint? = nil
class FixerForCarsLayouts: UICollectionViewLayout {
override func prepareForTransition(from oldLayout: UICollectionViewLayout) {
avoidAppleMessupCarsLayouts = collectionView?.contentOffset
}
override func targetContentOffset(
forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint {
if avoidAppleMessupCarsLayouts != nil {
return avoidAppleMessupCarsLayouts!
}
return super.targetContentOffset(forProposedContentOffset: proposedContentOffset)
}
}
以下是“汽车”屏幕的三个布局:
CarsLayout1: FixerForCarsLayouts { ...
CarsLayout2: FixerForCarsLayouts { ...
CarsLayout3: FixerForCarsLayouts { ...
就是这样。它现在工作了。
>
令人难以置信的是,你可能有不同的布局“集”(对于汽车,狗,房子等),它们可能会(可以想象)碰撞。因此,对于每个“集”,请像上面这样有一个全局类和一个基类。
这是多年前由路过的用户@Isaacliu发明的。
一个细节,艾萨克留的代码片段中的FWIW,最终确定了布局传输
被添加。事实上,这在逻辑上是没有必要的。
事实是,在Apple改变其工作方式之前,每次在集合视图布局之间进行动画处理时,您都必须这样做。这就是生活!
几天来,我一直在为这个问题苦恼,并找到了一个可能有所帮助的解决方案。就我而言,我有一个折叠的照片布局,就像ipad上的照片应用程序一样。它显示相册,照片相互叠加,当你点击相册时,它会展开照片。所以我有两个独立的UICollectionViewLayout,我用[self.collectionViewsetCollection ViewLayout: myLayout Animated: YES]
在动画之前,我遇到了单元格跳跃的确切问题,并意识到这是内容偏移
。我用content Offset
尝试了所有方法,但它仍然在动画中跳跃。泰勒上面的解决方案有效,但它仍然在扰乱动画。
然后我注意到,只有当屏幕上有几张专辑时,才会出现这种情况,而这些专辑还不足以填满屏幕。我的布局根据建议覆盖-(CGSize)collectionViewContentSize
。当只有几个相册时,集合视图内容大小小于视图内容大小。当我在集合布局之间切换时,这会导致跳转。
所以我在我的布局上设置了一个名为minHeight的属性,并将其设置为集合视图父级的高度。然后我在返回-(CGSize)Collection ViewContentSize
之前检查高度,我确保高度为
不是一个真正的解决方案,但它现在工作正常。我会尝试将集合视图的content Size
设置为至少是它包含视图的长度。
如果您从UICollectionViewFlowLayout继承,Manicaesar添加了一个简单的解决方法:
-(CGSize)collectionViewContentSize { //Workaround
CGSize superSize = [super collectionViewContentSize];
CGRect frame = self.collectionView.frame;
return CGSizeMake(fmaxf(superSize.width, CGRectGetWidth(frame)), fmaxf(superSize.height, CGRectGetHeight(frame)));
}
UICollectionViewLayout
包含可重写方法目标内容偏移对于提议内容偏移:
它允许您在布局更改期间提供正确的内容偏移量,这将正确设置动画。这在 iOS 7.0 及更高版本中可用
今天午刚睡醒就接到面试电话,用友java一面(因为海投,所以刚开始不知道面试的公司,面试官介绍他是哪个公司的时候,我也没听清楚,后面加了微信,问了一下才知道),开始就是自我介绍,然后开始挖项目,就是一通吹,然后自圆其说,然后java的基本类型有哪些?基本类型和引用类型的区别?mysql的索引,索引的底层数据结构,索引失效的场景?Spring boot的IOC aop,自动装配?环形链表?然后面到这
背景:我正在尝试迁移项目,以使用新的、升级的nexus实例,而不是旧的。Gradle项目和Maven项目进展顺利,但Grails项目进展并不顺利。 问题:发布和单独发布无法发布到新的nexus。快照发布工作正常。在旧的nexus中,快照和发布都工作得很好,我之前提到的使用相同用户凭据的Maven和Gradle项目也工作得很好。 错误如下 POM生成: /var/atlassian/applicat
我已经写了一个C程序,在这里我画了一个茶壶并应用了照明。它本身很简单,但我也使用着色器。简单我是GLSL新手我刚刚尝试了一个简单的片段着色器,但是屏幕输出令人费解。 在这个文件中,我在init方法中初始化了glew,在这里我还编译了顶点和片段着色器。它们位于“顶点着色器”和“片段着色器”文件中。 你可能不认识什么是Light和材质。它们只是一些包含有关灯的所有信息的结构。我已经测试了这些结构,所以
我有一个立方体,我只在x轴上的3个点(浮动位置)之间移动它。所以立方体将从0.00开始,我按下右键,它在x轴上向右移动到2.0f。然后我按下左键,它会回到0.0f。然后我再次按下左键,它会移动到-2.0f。按下右键应该会将其返回到0.0f,但会超出0。误差的大小取决于我移动的速度。 如果我从左键开始,结果也是一样的。 帧时间是
问题内容: 如何在Python中动态设置局部变量(变量名是动态的)? 问题答案: 与已经发布的其他答案相反,你不能直接修改并期望它可以正常工作。 修改未定义。在函数外部,当和相同时,它将起作用;在一个函数内部通常将不起作用。 使用字典,或在对象上设置属性: 或者,如果你愿意,可以使用一个类: 编辑:访问不是函数的名称空间中的变量(因此,模块,类定义,实例)通常是通过字典查找来完成的(如Sven在注