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

kus*_*uya 59 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;
}
Run Code Online (Sandbox Code Playgroud)

rav*_*ron 74

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

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

如果您查看文档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"];
Run Code Online (Sandbox Code Playgroud)

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


Kou*_*hik 35

Swift 3.0和Swift 4.0

UICollectionView

该应用程序在UICollectionView初始化时启动后立即崩溃

初始化 如下(上图viewDidLoad)

let alarmCollectionView:UICollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())
let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()
Run Code Online (Sandbox Code Playgroud)

在方法(内部viewDidLoad)

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

在初始化之后工作得很好我使用Autolayout所以使用CGRect.zero或使用你自己的CGRect

UICollectionViewController

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

 let  testNavController:UINavigationController = UINavigationController.init()
 let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init() 
 let collectionView:UICollectionViewController = UICollectionViewController.init(collectionViewLayout:layout )              
 testNavController.pushViewController(collectionView, animated: true)
Run Code Online (Sandbox Code Playgroud)


Wil*_* Hu 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")
Run Code Online (Sandbox Code Playgroud)


can*_*ine 7

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")
    }
}
Run Code Online (Sandbox Code Playgroud)


Sou*_*har 6

在斯威夫特

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


小智 5

Swift 3.0、Swift 4.0 和 Swift 5.0

这对我有用。

let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())
Run Code Online (Sandbox Code Playgroud)

在方法中(在 viewDidLoad 中)

if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
    flowLayout.scrollDirection = .horizontal
}
Run Code Online (Sandbox Code Playgroud)