[英]UICollectionView Will Not Update Its Layout On Screen Rotation
I have a custom UIView
with a UICollectionView
. 我有一个带有UICollectionView
的自定义UIView
。
On screen rotation I am trying to get the UICollectionView
to stretch across the screen, and then redraw its cells. 在屏幕旋转时,我试图使UICollectionView
延伸到整个屏幕,然后重绘其单元格。
After I had the data downloaded I tried both [grid setNeedsLayout]
and [grid setNeedsDisplay]
but that didn't work. 下载完数据后,我尝试了[grid setNeedsLayout]
和[grid setNeedsDisplay]
但这没有用。
This is what I want to happen: 这就是我想发生的事情:
Portrait 肖像
Landscape 景观
(This is also how it appears when the app is started in landscape, but if you change to portrait it doens't update.) (这也是当应用在横向模式下启动时的外观,但如果更改为纵向模式,则不会更新。)
But this is what I get if I start in Portrait
mode and switch to Landscape
. 但这是我从Portrait
模式开始并切换到Landscape
。
I have tried: 我努力了:
-(void)viewDidLayoutSubviews {
grid = [[MyThumbnailGridView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height/2, self.view.frame.size.width, self.view.frame.size.height/2)];
}
I have also tried toying with: 我也尝试过玩弄:
- (void) viewWillLayoutSubviews {
UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsLandscape(interfaceOrientation))
{
//LANDSCAPE
if(grid){
NSLog(@"Grid Needs Landscape Layout");
grid.frame =CGRectMake(0, self.view.frame.size.height/2, self.view.frame.size.width, self.view.frame.size.height/2);
[grid refreshData];
}
}else {
//PORTRIAT
if(grid){
NSLog(@"Grid Needs Portrait Layout");
grid.frame =CGRectMake(0, self.view.frame.size.height/2, self.view.frame.size.width, self.view.frame.size.height/2);
[grid refreshData];
}
}
}
But I can't get it to stretch. 但是我无法伸展它。
Any help? 有什么帮助吗?
MyThumbnailGridView MyThumbnailGridView
@interface ViewController () <UINavigationControllerDelegate> {
MyThumbnailGridView *grid;
NSMutableArray * arrImages;
}
- (void)viewDidLoad {
[super viewDidLoad];
arrImages = [NSMutableArray new];
grid = [[MyThumbnailGridView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height/2, self.view.frame.size.width, self.view.frame.size.height/2)];
//grid = [[MyThumbnailGridView alloc] initWithFrame:CGRectZero];
NSLog(@"showThumbnailGrid Grid View Size: %@", NSStringFromCGRect(grid.frame));
[self.view addSubview:grid];
[self getListOfImages];
}
-(void) getListOfImages {
//Do background task to get images and fill arrImages
[self onDownloadImageDataComplete];
}
- (void) onDownloadImageDataComplete{
grid.imageDataSource = arrImages;
// [grid setNeedsLayout];
// [grid setNeedsDisplay];
}
//...
@end
*MyThumbnailGridView.h * MyThumbnailGridView.h
@interface MyThumbnailGridView : UIView
-(id)initWithFrame:(CGRect)frame;
-(void) refreshData;
@property (nonatomic,strong) NSArray *imageDataSource;
@end
*MyThumbnailGridView.m * MyThumbnailGridView.m
@interface MyThumbnailGridView () <UICollectionViewDelegate, UICollectionViewDataSource>{
UICollectionView *collectionView;
}
@end
@implementation MyThumbnailGridView
- (instancetype) initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if(self){
[self customInit];
}
return self;
}
- (void) customInit {
collectionView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:[[MyFlowLayout alloc] init]];
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.allowsMultipleSelection = NO;
collectionView.showsVerticalScrollIndicator = YES;
[collectionView setBackgroundColor:[UIColor darkGrayColor]];
[collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"MyId"];
[self addSubview:collectionView];
}
- (void) refreshData {
NSLog(@"Refresh Grid Data");
[collectionView reloadData];
}
////other code
@end
MyFlowLayout MyFlowLayout
@interface MyFlowLayout : UICollectionViewFlowLayout
@end
@implementation MyFlowLayout
- (instancetype)init{
self = [super init];
if (self)
{
self.minimumLineSpacing = 1.0;
self.minimumInteritemSpacing = 1.0;
self.scrollDirection = UICollectionViewScrollDirectionVertical;
}
return self;
}
- (CGSize)itemSize {
NSInteger numberOfColumns = 3;
CGFloat itemWidth = (CGRectGetWidth(self.collectionView.frame) - (numberOfColumns - 1)) / numberOfColumns;
return CGSizeMake(itemWidth, itemWidth);
}
@end
MyCollectionViewCell MyCollectionViewCell
@interface MyCollectionViewCell : UICollectionViewCell
@property (strong, nonatomic) UIImageView *imageView;
@end
@implementation MyCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.imageView = [UIImageView new];
[self.imageView setContentMode:UIViewContentModeScaleAspectFill];
[self.imageView setClipsToBounds:YES];
[self.imageView setBackgroundColor:[UIColor darkGrayColor]];
[self.contentView addSubview:self.imageView];
}
return self;
}
- (void)prepareForReuse {
[super prepareForReuse];
self.imageView.image = nil;
[self.imageView setHidden:NO];
}
- (void)layoutSubviews {
[super layoutSubviews];
[self.imageView setFrame:self.contentView.bounds];
}
@end
This can be solved with either you can change the frame of MyThumbnailGridView
view in delegate function of orientation or create the view with constraints like this 可以通过以下方法解决此问题:您可以在方向的委托函数中更改MyThumbnailGridView
视图的框架,或者创建具有此类约束的视图
(void)viewDidLoad {
[super viewDidLoad];
arrImages = [NSMutableArray new];
grid = [[MyThumbnailGridView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height/2, self.view.frame.size.width, self.view.frame.size.height/2)];
[self.view addSubview:grid];
[self getListOfImages];
}
-(void)viewDidLayoutSubviews
{
if(Once){
Once = NO;
// adding constraints
MyThumbnailGridView.translatesAutoresizingMaskIntoConstraints = NO;
[self.MyThumbnailGridView.widthAnchor constraintEqualToConstant:self.view.frame.size.width].active = YES;
[self.MyThumbnailGridView.heightAnchor constraintEqualToConstant:self.view.frame.size.height/2].active = YES;
[self.MyThumbnailGridView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].active = YES;
[self.MyThumbnailGridView.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:self.view.frame.size.height/2].active = YES;
}
}
Also implement this 还要实现
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[self.view layoutIfNeeded];
[MyThumbnailGridView.collectionView invalidate];
// Do view manipulation here.
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
The problem is that the collection view itself is not changing size when the app rotates. 问题在于,当应用程序旋转时,集合视图本身不会更改大小。 You have given the collection view a fixed frame
and then just walked away. 您已为集合视图提供了固定的frame
,然后就走开了。 So it never changes. 因此,它永远不会改变。 So never lays itself out again. 因此,永远不要再摆出自己的位置。
You should give your MyThumbnailGridView and its collection view subview autolayout contraints to their superviews, so that they change size correctly when the app rotates. 您应将MyThumbnailGridView及其集合视图子视图的自动布局约束赋予其超级视图,以使它们在应用程序旋转时正确更改大小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.