UICollectionView:必须使用非零布局参数进行初始化

时间:2014-06-18 15:01:29

标签: ios uicollectionview

我在代码中添加了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;
}

7 个答案:

答案 0 :(得分:66)

崩溃告诉你很明显出了什么问题:

  

必须使用非零布局参数初始化UICollectionView。

如果您选中the documentation for UICollectionView,则会发现唯一的初始化程序为initWithFrame:collectionViewLayout:。此外,在该初始值设定项的参数中,您将看到:

  

     

集合视图的框架矩形,以磅为单位。框架的原点相对于您计划添加它的superview。在初始化期间,此帧将传递给超类。

     

布局

     

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

加粗重要部分。您必须使用initWithFrame:collectionViewLayout:初始化UICollectionView,并且必须将其传递给非零UICollectionViewLayout个对象。


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

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"];

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

答案 1 :(得分:28)

Swift 3.0和Swift 4.0

<强> UICollectionView

应用程序在初始化<?php session_start(); include ('../../class/connection.php'); $sql = "UPDATE reservationmenutable SET service = ? WHERE id = ?"; $statement = $conn->prepare($sql); foreach ($_POST["hidden_id"] as $key => $db_id) { foreach ($_POST["service_id"] as $key => $service_key) { $statement->execute([$service_key, $db_id ]); } } ?> 时启动后立即崩溃

初始化 <{em>

UICollectionView

方法(在viewDidLoad内)

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

在初始化之后工作正常我正在使用Autolayout,因此使用viewDidLoad或使用您自己的layout.scrollDirection = UICollectionViewScrollDirection.vertical alarmCollectionView.setCollectionViewLayout(layout, animated: true) alarmCollectionView.delegate = self alarmCollectionView.dataSource = self alarmCollectionView.backgroundColor = UIColor.clear self.addSubview(alarmCollectionView)

<强> UICollectionViewController

如果您使用的是CGRect.zero而不是CGRect,则需要在初始化时添加布局

UICollectionViewController

答案 2 :(得分:18)

只是 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")

答案 3 :(得分:5)

Swift 5一般解决方案

可以使用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")
    }
}

答案 4 :(得分:0)

不要setCollectionViewLayout喜欢: [self.collectionView setCollectionViewLayout:flowLayout]; 尝试在初始化时设置: [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:defaultLayout];

答案 5 :(得分:0)

在Swift中

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

答案 6 :(得分:0)

Swift 3.0,Swift 4.0和Swift 5.0

这对我有用。

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

在方法中(在viewDidLoad内部)

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