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

Refresh

December 2018

Views

47.2k time

44

I added UICollectionView by 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?
CollectionCell is custom class of 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;
}

4 answers

62

Катастрофа говорит вам довольно явно, что происходит не так:

UICollectionView должен быть инициализирован с параметром макета, не ноль.

Если проверить документацию дляUICollectionView , вы обнаружите , что только инициализатор initWithFrame:collectionViewLayout:. Кроме того, в параметрах этого инициализаторе, вы увидите:

Рамка

Рамки прямоугольник для сбора зрения, измеряется в пунктах. Происхождение кадра относительно надтаблицы, в которой вы собираетесь добавить. Этот кадр передается в суперкласс во время инициализации.

расположение

Объект макета использовать для организации элементов. Представление коллекции хранит сильную ссылку на указанный объект. Не должно быть нулевым.

Я полужирный важную роль. Вы должны использовать 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. Если это не так, вставить любой кадр вы хотите вместо этого.

0

не setCollectionViewLayout Понравилось: [self.collectionView setCollectionViewLayout: FlowLayout]; попытаться установить, когда инициализации: [[UICollectionView Alloc] initWithFrame: рамка collectionViewLayout: defaultLayout];

22

Swift 3.0 и 4.0 Swift

UICollectionView

Приложение разбился , как только он начал , когда UICollectionViewинициализируется

инициализации , как ниже (выше viewDidLoad)

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

В способе (внутри viewDidLoad)

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

Работал отлично после инициализации , как это я использую 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)
17

Просто быстры версия Райли Avron ответа «s

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