Objective-C:无Storyboard/Xib时,将UICollectionView布局移至对应控制器
解决方案:将UICollectionView布局封装到CollectionViewController内部
你说得对,UICollectionViewController的指定初始化方法确实是initWithCollectionViewLayout:,必须传入布局对象才能完成初始化,但我们完全可以把布局的创建逻辑封装到CollectionViewController内部,让外部调用更简洁,同时把布局代码集中到它该待的地方。这里有两种常用的实现方式:
方式一:自定义便捷初始化方法
在CollectionViewController中添加一个无参的便捷初始化方法,内部自行创建并配置布局,再调用指定初始化方法。
1. 在CollectionViewController.h中声明方法
@interface CollectionViewController : UICollectionViewController - (instancetype)init; @end
2. 在CollectionViewController.m中实现方法
@implementation CollectionViewController - (instancetype)init { // 在这里创建并配置布局 UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20); layout.minimumInteritemSpacing = 0; layout.minimumLineSpacing = 20; // 调用指定初始化方法传入布局 self = [super initWithCollectionViewLayout:layout]; if (self) { // 这里可以添加其他初始化逻辑 } return self; } // 可选:规范起见,重写指定初始化方法以支持外部传入自定义布局 - (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout { self = [super initWithCollectionViewLayout:layout]; if (self) { // 若外部传入布局,可在此做额外适配 } return self; } @end
3. 在FirstViewController中调用
现在你只需要简单初始化即可,不用再处理布局细节:
CollectionViewController *ivc = [[CollectionViewController alloc] init]; [self.navigationController pushViewController:ivc animated:NO];
方式二:直接重写默认init方法(无需额外声明)
如果不想新增方法,也可以直接重写init方法,逻辑和上面一致:
@implementation CollectionViewController - (instancetype)init { UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20); layout.minimumInteritemSpacing = 0; layout.minimumLineSpacing = 20; self = [super initWithCollectionViewLayout:layout]; return self; } @end
注意事项
- 不建议把布局配置放到
viewDidLoad:虽然在viewDidLoad中修改布局属性也能生效,但UICollectionViewController在初始化阶段就已经用传入的布局创建了collectionView,初始化时传入正确的布局是更符合设计逻辑的做法。 - 若需动态调整布局(比如适配不同屏幕尺寸),可以在
viewWillLayoutSubviews中更新布局属性,这个时机修改布局是安全且有效的。
内容的提问来源于stack exchange,提问作者terk
相关产品推荐
相关产品推荐

