Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
356 views
in Technique[技术] by (71.8m points)

swift - Thread 1: "UICollectionView must be initialized with a non-nil layout parameter

I'm new to swift and I'm learning how to make a simple app programmatically so I follow a tutorial and I wrote the layout codes in a separate class "HomeView" and I have the main controller "HomeViewController". the problem is I want to sit a dataSource and delegate for the collection in the HomeViewController but I can't I have this error "Thread 1: "UICollectionView must be initialized with a non-nil layout parameter" I made the layout in the HomeView class but the HomeViewController doesn't recognize it

import UIKit

class HomeView: UIView {
    
    weak var homeViewController: HomeViewController? {
        didSet {
            setupHomeView()
        }
    }
            
   
    let firstArtistLabel: UILabel = {
        let label = UILabel()
        label.text = "New Stories"
        label.textAlignment = .left
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let newCollection: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collection = UICollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: layout)
        collection.translatesAutoresizingMaskIntoConstraints = false
//        collection.backgroundColor = UIColor.yellow
        collection.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")


        collection.isScrollEnabled = true
       // collection.contentSize = CGSize(width: 2000 , height: 400)
        return collection
     }()


    let scrollView: UIScrollView = {
        let sv = UIScrollView()
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()
    
    let contentView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupViews() {
        backgroundColor = .white
        
        addSubview(scrollView)
        scrollView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        scrollView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

        scrollView.addSubview(contentView)
        contentView.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true
        contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        contentView.rightAnchor.constraint(equalTo: scrollView.rightAnchor).isActive = true
        contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
        contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

        
        
        
        
        contentView.addSubview(firstArtistLabel)
        firstArtistLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 8).isActive = true
        firstArtistLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 26).isActive = true
        firstArtistLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
        firstArtistLabel.heightAnchor.constraint(equalToConstant: 36).isActive = true

        
        contentView.addSubview(newCollection)
        newCollection.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
        newCollection.topAnchor.constraint(equalTo: firstArtistLabel.bottomAnchor).isActive = true
        newCollection.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
        newCollection.heightAnchor.constraint(equalToConstant: 336).isActive = true


    
    private func setupHomeView() {
        translatesAutoresizingMaskIntoConstraints = false
        if let homeViewController = homeViewController {
            homeViewController.view.addSubview(self)
            leftAnchor.constraint(equalTo: homeViewController.view.leftAnchor).isActive = true
            rightAnchor.constraint(equalTo: homeViewController.view.rightAnchor).isActive = true
            topAnchor.constraint(equalTo: homeViewController.view.topAnchor).isActive = true
            bottomAnchor.constraint(equalTo: homeViewController.view.bottomAnchor).isActive = true
        }
    }
    
} 


   

The HomeViewController


class HomeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    
    
    let homeView: HomeView = {
        let view = HomeView()
        return view
    }()
    
    var newCollection = UICollectionView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
      
        homeView.homeViewController = self
    }
    
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 6
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = newCollection.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.backgroundColor = .blue

        return cell
    }
    

question from:https://stackoverflow.com/questions/65621448/thread-1-uicollectionview-must-be-initialized-with-a-non-nil-layout-parameter

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Why are you adding in your View Controller:

var newCollection = UICollectionView()

Since you already added it in your view?, instead you should set your view as your view type, and reference that collection view from the your View Controller.

var myView: CustomView

myView = MyView()
view = myView
let collectionView = myView.collectionView

Every collection view needs a UICollectionViewLayout subclass in its initializer, now UICollectionViewLayout is a abstract class, you can make your own, but you could also use UICollectionViewFlowLayout() in this case:

var newCollection = UICollectionView(collectionViewLayout: UICollectionViewFlowLayout())

Now you did add it on your first view, but not in the second one, again check why the second one exists, that's the one causing the problems.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...