我正在尝试使用 AutoLayout 以编程方式创建 UICollectionView,但我遇到了一些问题。
第一次测试:
在我的第一次尝试中,我创建了一个 UICollectionView 作为 Lazy var 并将其添加到 viewDidLoad 中,如下所示:
lazy var collection: UICollectionView = {
let cv = UICollectionView()
cv.translatesAutoresizingMaskIntoConstraints = false
cv.setCollectionViewLayout(self.flowLayout, animated: true)
cv.dataSource = self
cv.delegate = self
cv.registerClass(MyViewCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.collection)
}
这个方法让我犯了这个错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'
第二个测试:
所以我不得不使用 frame/collectionViewLayout 初始值设定项,我的第二次尝试如下所示:
lazy var collection: UICollectionView = {
let cv = UICollectionView(frame: UIScreen.mainScreen().bounds, collectionViewLayout: self.flowLayout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.setCollectionViewLayout(self.flowLayout, animated: true)
cv.dataSource = self
cv.delegate = self
cv.registerClass(MenuViewCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.collection)
//Constraints was there...
}
使用此方法我得到一个空白屏幕,使用调试器我发现调用了数据源委托(delegate)方法(numberOfItemsInSection
和numberOfSectionsInCollectionView
) ,但没有调用其他委托(delegate)方法(sizeForItemAtIndexPath
和 cellForItemAtIndexPath
)
所以我决定摆脱 autoLayout,看看它的工作方式。
第三个测试:
lazy var collection: UICollectionView = {
let cv = UICollectionView(frame: UIScreen.mainScreen().bounds, collectionViewLayout: self.flowLayout)
// cv.translatesAutoresizingMaskIntoConstraints = false
cv.setCollectionViewLayout(self.flowLayout, animated: true)
cv.dataSource = self
cv.delegate = self
cv.registerClass(MenuViewCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.collection)
//No more constraints here !!!
}
一切正常。
所以,我的问题是:有没有办法以编程方式将 UICollectionView 与 AutoLayout 一起使用?
解决方案
一段时间后,我发现我的问题出在约束上。然后我想出了这个解决方案:
let slice = (UIScreen.mainScreen().bounds.height / CGFloat(3.0))
lazy var flowLayout:UICollectionViewFlowLayout = {
let f = UICollectionViewFlowLayout()
f.scrollDirection = UICollectionViewScrollDirection.Horizontal
return f
}()
lazy var collection: UICollectionView = {
let cv = UICollectionView(frame: CGRectZero, collectionViewLayout: self.flowLayout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.setCollectionViewLayout(self.flowLayout, animated: true)
cv.dataSource = self
cv.delegate = self
cv.registerClass(MenuViewCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.collection)
let views = ["collection":self.collection]
var constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[collection]-0-|", options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: views)
self.view.addConstraints(constraints)
constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:|-\(slice)-[collection]-\(slice)-|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views)
self.view.addConstraints(constraints)
}
最佳答案
过了一会儿,我发现我的问题出在约束上。然后我想出了这个解决方案:
let slice = (UIScreen.mainScreen().bounds.height / CGFloat(3.0))
lazy var flowLayout:UICollectionViewFlowLayout = {
let f = UICollectionViewFlowLayout()
f.scrollDirection = UICollectionViewScrollDirection.Horizontal
return f
}()
lazy var collection: UICollectionView = {
let cv = UICollectionView(frame: CGRectZero, collectionViewLayout: self.flowLayout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.setCollectionViewLayout(self.flowLayout, animated: true)
cv.dataSource = self
cv.delegate = self
cv.registerClass(MenuViewCell.self, forCellWithReuseIdentifier: "cell")
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.collection)
let views = ["collection":self.collection]
var constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[collection]-0-|", options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: views)
self.view.addConstraints(constraints)
let stringConstraint = "V:|-\(slice)-[collection]-\(slice)-|"
print("stringConstraint: \(stringConstraint)")
constraints = NSLayoutConstraint.constraintsWithVisualFormat(stringConstraint, options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views)
self.view.addConstraints(constraints)
}
关于ios - 使用 AutoLayout 以编程方式创建 UICollectionView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33770558/