Reputation: 698
You can see from the code below that layout parameter has been set inside ViewDidLoad()
, but it gives me an error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'
var layer: UICollectionViewFlowLayout = {
var item = UICollectionViewFlowLayout()
item.itemSize = CGSize(width: 100, height: 100)
return item
}()
UICollectionView
object has been set in property initializer because obviously I want this UICollectionView
object to be accessible globally:
var dataCollectionViews = UICollectionView()
viewDidLoad(){
dataCollectionViews = UICollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0) , collectionViewLayout: self.layer)
view.addSubview(dataCollectionViews)
self.dataCollectionViews.delegate = self
self.dataCollectionViews.dataSource = self
self.dataCollectionViews.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewReuse)
self.dataCollectionViews.layer.cornerRadius = 10
self.dataCollectionViews.translatesAutoresizingMaskIntoConstraints = false
self.dataCollectionViews.isHidden = true
changed()
}
When I moved contents inside changed()
to inside of viewDidLoad()
and initialized dataCollectionViews inside of viewDidLoad()
, everything worked as intended, showing UICollectionView
object when selecting first button of segmented Control.
@objc func changed() {
if segmentTime.selectedSegmentIndex == 0 {
self.dataCollectionViews.isHidden = false
let dataCollectionTop = NSLayoutConstraint(item: self.dataCollectionViews, attribute: .top, relatedBy: .equal, toItem: sortLabel, attribute: .bottom, multiplier: 1.0, constant: 10)
let dataCollectionLeft = NSLayoutConstraint(item: self.dataCollectionViews, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1.0, constant: 10)
let dataCollectionRight = NSLayoutConstraint(item: self.dataCollectionViews, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1.0, constant: -10)
let dataCollectionHeight = NSLayoutConstraint(item: self.dataCollectionViews, attribute: .height, relatedBy: .equal, toItem: self.view, attribute: .height, multiplier: 520/812, constant: 0)
let dataCollectionWidth = NSLayoutConstraint(item: self.dataCollectionViews, attribute: .width, relatedBy: .equal, toItem: self.view, attribute: .width, multiplier: 355/375, constant: 0)
NSLayoutConstraint.activate([dataCollectionLeft, dataCollectionRight, dataCollectionHeight, dataCollectionWidth, dataCollectionTop])
}
if segmentTime.selectedSegmentIndex == 1 {
}
if segmentTime.selectedSegmentIndex == 2 {
}
}
I'd love to try to set dataCollectionViews object in property initializer but I know it is not possible, but it seems like dataCollectionViews
needs be initialized with UICollectionViewFlowLayout()
on first try. What other alternative is available?
Upvotes: 0
Views: 184
Reputation: 14841
How about something like this?
private lazy var collectionView: UICollectionView = {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 188.0, height: 268.0)
let result: UICollectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
result.register(CellClass.self, forCellWithReuseIdentifier: "cell")
result.dataSource = self
result.delegate = self
return result
}()
Upvotes: 1