集合视图不会在旋转时更新布局
Collection View does not update layout at Rotation
这是应用程序处于纵向模式时的视图。
当它旋转到横向模式时,它看起来像这样
视图调试器显示 UIWindow
没有像这里显示的那样旋转
UICollectionViewController
是通过 StoryBoard 创建的。我已经尝试子类化 UICollectionViewFlowLayout
来实现 shouldInvalidateLayoutForBoundsChange
,但它没有解决我的问题。
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
CGRect oldBounds = self.collectionView.bounds;
if (CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds)) {
return YES;
}
return NO;
}
请提供下一步要检查的内容或请求额外代码进行调试的想法。
编辑 - 正如 MirekE 所建议的,我试图向 CollectionView
添加约束,但没有成功。 Editor->Pin 的所有选项对于 CollectionView
都不可用。
编辑,回复 Andrea -
我的目标是 iOS8.3。我的理解是旋转调用的主要方法是viewWillTransitionToSize:withTransitionCoordinator:
,它来自UIContentContainer
protocol。我已将以下内容添加到我的 CollectionViewController,但同样的问题仍然存在
-(void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator {
[self.collectionView.collectionViewLayout invalidateLayout];
[self.collectionView reloadData];
}
看起来您只是将集合视图拖到 canvas 上,但没有添加任何约束。因此,当您旋转设备时,尺寸不会改变。
在 Storyboard select 集合视图中,然后单击 Xcode 底部的 Pin 图标并为顶部、左侧、底部和右侧边距添加约束。执行此操作后,集合视图应在旋转时调整大小。
我不知道你的目标是哪个 iOS 版本,但我假设你知道旋转过程和在视图控制器中调用的方法。
在其中一种方法中,您只需调用:
[self.collectionView.collectionViewLayout invalidateLayout];
可能取决于您的布局-reloadData
无需子类化。
编辑
我使用这种方法,我想这不起作用,因为您应该在调整大小后重新布局集合:
- (void) willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self.collectionView.collectionViewLayout invalidateLayout];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self.collectionView reloadData];
}];
}
我正在做的是将布局失效过程附加到动画过程。
问题是 collectionView
插座设置不正确。设置collectionView
后,一切正常。
collectionView
插座未设置:
collectionView
插座组:
如果您有 UICollectionViewLayout 的自定义实现,请尝试覆盖方法:
override public func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
let bounds = self.collectionView!.bounds;
return ((CGRectGetWidth(newBounds) != CGRectGetWidth(bounds) ||
(CGRectGetHeight(newBounds) != CGRectGetHeight(bounds))));
}
override public func invalidateLayout() {
cache.removeAll() // remove layout attributes ans settings if they exist
super.invalidateLayout()
}
干杯!
这是应用程序处于纵向模式时的视图。
当它旋转到横向模式时,它看起来像这样
视图调试器显示 UIWindow
没有像这里显示的那样旋转
UICollectionViewController
是通过 StoryBoard 创建的。我已经尝试子类化 UICollectionViewFlowLayout
来实现 shouldInvalidateLayoutForBoundsChange
,但它没有解决我的问题。
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
CGRect oldBounds = self.collectionView.bounds;
if (CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds)) {
return YES;
}
return NO;
}
请提供下一步要检查的内容或请求额外代码进行调试的想法。
编辑 - 正如 MirekE 所建议的,我试图向 CollectionView
添加约束,但没有成功。 Editor->Pin 的所有选项对于 CollectionView
都不可用。
编辑,回复 Andrea -
我的目标是 iOS8.3。我的理解是旋转调用的主要方法是viewWillTransitionToSize:withTransitionCoordinator:
,它来自UIContentContainer
protocol。我已将以下内容添加到我的 CollectionViewController,但同样的问题仍然存在
-(void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator {
[self.collectionView.collectionViewLayout invalidateLayout];
[self.collectionView reloadData];
}
看起来您只是将集合视图拖到 canvas 上,但没有添加任何约束。因此,当您旋转设备时,尺寸不会改变。
在 Storyboard select 集合视图中,然后单击 Xcode 底部的 Pin 图标并为顶部、左侧、底部和右侧边距添加约束。执行此操作后,集合视图应在旋转时调整大小。
我不知道你的目标是哪个 iOS 版本,但我假设你知道旋转过程和在视图控制器中调用的方法。
在其中一种方法中,您只需调用:
[self.collectionView.collectionViewLayout invalidateLayout];
可能取决于您的布局-reloadData
无需子类化。
编辑
我使用这种方法,我想这不起作用,因为您应该在调整大小后重新布局集合:
- (void) willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self.collectionView.collectionViewLayout invalidateLayout];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
[self.collectionView reloadData];
}];
}
我正在做的是将布局失效过程附加到动画过程。
问题是 collectionView
插座设置不正确。设置collectionView
后,一切正常。
collectionView
插座未设置:
collectionView
插座组:
如果您有 UICollectionViewLayout 的自定义实现,请尝试覆盖方法:
override public func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
let bounds = self.collectionView!.bounds;
return ((CGRectGetWidth(newBounds) != CGRectGetWidth(bounds) ||
(CGRectGetHeight(newBounds) != CGRectGetHeight(bounds))));
}
override public func invalidateLayout() {
cache.removeAll() // remove layout attributes ans settings if they exist
super.invalidateLayout()
}
干杯!