ios UICollectionView:必须使用非 nil 布局参数初始化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24288927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:57:14  来源:igfitidea点击:

UICollectionView: must be initialized with a non-nil layout parameter

iosuicollectionview

提问by kusumoto_teruya

I added UICollectionViewby code.
Now, the app crash with message: UICollectionView must be initialized with a non-nil layout parameter.
Do you have any idea to fix it?
CollectionCellis custom class of UICollectionViewCell.

我是UICollectionView通过代码添加的。
现在,应用程序崩溃并显示消息:UICollectionView must be initialized with a non-nil layout parameter
你有什么办法解决它吗?
CollectionCell是 的自定义类UICollectionViewCell

@property (nonatomic, strong) UICollectionView* collectionView;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.collectionView = [[UICollectionView alloc]init];
    [self.collectionView registerClass:[CollectionCell class] forCellWithReuseIdentifier:@"cell"];
    UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
    flowLayout.itemSize = CGSizeMake(100, 100);
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    [self.collectionView setCollectionViewLayout:flowLayout];

    self.collectionView.frame = CGRectMake(0, 60, 320, 500);
    self.collectionView.backgroundColor = [UIColor whiteColor];
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    [self.view addSubview:self.eventCollection];
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 20;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CollectionCell* cell = [self.eventCollection dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    cell.label.text = [NSString stringWithFormat:@"%d", indexPath.item];
    return cell;
}

回答by ravron

The crash is telling you pretty explicitly what is going wrong:

崩溃非常明确地告诉您出了什么问题:

UICollectionView must be initialized with a non-nil layout parameter.

UICollectionView 必须使用非 nil 布局参数进行初始化。

If you check the documentation for UICollectionView, you'll find that the only initializer is initWithFrame:collectionViewLayout:. Further, in the parameters for that initializer, you'll see:

如果您查看的文档UICollectionView,您会发现唯一的初始值设定项是initWithFrame:collectionViewLayout:. 此外,在该初始化程序的参数中,您将看到:

frame

The frame rectangle for the collection view, measured in points. The origin of the frame is relative to the superview in which you plan to add it. This frame is passed to the superclass during initialization.

layout

The layout object to use for organizing items. The collection view stores a strong reference to the specified object. Must not be nil.

框架

集合视图的框架矩形,以点为单位。框架的原点与您计划添加它的超级视图相关。该帧在初始化期间传递给超类。

布局

用于组织项目的布局对象。集合视图存储对指定对象的强引用。不得为零。

I've boldedthe important part. You must use initWithFrame:collectionViewLayout:to initialize your UICollectionView, and you must pass it a non-nil UICollectionViewLayoutobject.

我把重要的部分加粗了。您必须使用initWithFrame:collectionViewLayout:来初始化您的UICollectionView,并且您必须将它传递给一个非 nilUICollectionViewLayout对象。



One way to fix this, then, would be to simply change the order of initialization you do:

那么,解决此问题的一种方法是简单地更改您执行的初始化顺序:

UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.itemSize = CGSizeMake(100, 100);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];

Note that in the above example, I've assumed you want to use self.view.frameas the frame of self.collectionView. If that's not the case, insert whatever frame you want instead.

请注意,在上面的示例中,我假设您要self.view.frame用作self.collectionView. 如果不是这种情况,请插入您想要的任何框架。

回答by Koushik

Swift 3.0 and Swift 4.0

Swift 3.0 和 Swift 4.0

UICollectionView

用户界面集合视图

The app crashed as soon as it launched when UICollectionViewis initialised

该应用程序在UICollectionView初始化时一启动就崩溃了

initialize likebelow(above viewDidLoad)

初始化如下(上viewDidLoad

let alarmCollectionView:UICollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())
let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()

In Method(inside viewDidLoad)

在方法中(内部viewDidLoad

layout.scrollDirection = UICollectionViewScrollDirection.vertical
alarmCollectionView.setCollectionViewLayout(layout, animated: true)
alarmCollectionView.delegate = self
alarmCollectionView.dataSource = self
alarmCollectionView.backgroundColor = UIColor.clear
self.addSubview(alarmCollectionView)

Worked fine after initialising like this I am using Autolayout so using CGRect.zeroor use your own CGRect

像这样初始化后工作正常我正在使用 Autolayout 所以使用CGRect.zero或使用你自己的CGRect

UICollectionViewController

UICollectionViewController

In case if you are using UICollectionViewControllerinstead of UICollectionViewyou need to add layout when initialization

如果您正在使用UICollectionViewController而不是UICollectionView在初始化时需要添加布局

 let  testNavController:UINavigationController = UINavigationController.init()
 let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init() 
 let collectionView:UICollectionViewController = UICollectionViewController.init(collectionViewLayout:layout )              
 testNavController.pushViewController(collectionView, animated: true)

回答by William Hu

Just a swift version of Riley Avron's answer

只是Riley Avron答案的快速版本

    let layout = UICollectionViewFlowLayout()
    layout.itemSize = CGSizeMake(100, 100)
    let collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: layout)
    self.view.addSubview(collectionView)
    collectionView.delegate   = self
    collectionView.dataSource = self
    collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellIdentifier")

回答by John Corder

Swift 3.0, Swift 4.0 and Swift 5.0

Swift 3.0、Swift 4.0 和 Swift 5.0

It's work for me.

这对我有用。

let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())

In Method (inside viewDidLoad)

在方法中(在 viewDidLoad 中)

if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    flowLayout.scrollDirection = .horizontal
}

回答by candyline

Swift 5 general solution

Swift 5 通用解决方案

Can use UICollectionViewDelegateFlowLayout and don't forget to set your cell size

可以使用 UICollectionViewDelegateFlowLayout 并且不要忘记设置您的单元格大小

class YourViewController : UICollectionViewController, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize.init(width: view.frame.width, height: 250)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
    }
    // initialized with a non-nil layout parameter
    init() {
        super.init(collectionViewLayout: UICollectionViewFlowLayout())
    }    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

回答by Sourabh Kumbhar

In Swift

在斯威夫特

var collectionView: UICollectionView!
let layout = UICollectionViewFlowLayout()
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
layout.scrollDirection = .vertical
view.addSubview(collectionView)

回答by Semyon

don't setCollectionViewLayout liked this:

不要 setCollectionViewLayout 喜欢这个:

[self.collectionView setCollectionViewLayout:flowLayout];

try to set when init:

初始化时尝试设置:

[[UICollectionView alloc] initWithFrame:frame collectionViewLayout:defaultLayout];