我最近開始使用Swift,並試圖從頁面上的一個UICollectionView(工作)到兩個其中。我收到錯誤對於多個UICollectionView,出現錯誤,「...必須用非零布局進行初始化」
「終止應用程序由於未捕獲的異常‘NSInvalidArgumentException’的,理由是:‘UICollectionView必須以非空佈局參數初始化’」。
什麼我迄今發現的堆棧溢出已納入我的代碼,但我仍然得到錯誤。我在智慧的結尾,請幫助!
我去過的地方:
- 我開始與this article上建立UICollectionView,一切工作就好了。
- 現在要在同一屏幕上設置第二個UICollectionView,我按照this article中的說明操作。
- 似乎一切都還好,我得到「打造成功」,隨後立即進行崩潰的應用程序開始運行。錯誤消息說:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'
- 尋找在StackOverflow上的錯誤,我發現this article(與單UICollectionView交易,而不是兩個,我有)。
- 我實現了我所能那篇文章,但我仍然得到錯誤,而現在的想法。我的代碼如下,任何幫助將非常感謝!
ViewController.swift:
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
var collectionViewLeft = UICollectionView() // changed "let" to "var" so I can assign things to it in viewDidLoad()
var collectionViewRight = UICollectionView()
let collectionViewLeftIdentifier = "CollectionViewLeftCell"
let collectionViewRightIdentifier = "CollectionViewRightCell"
override func viewDidLoad() {
super.viewDidLoad()
let layoutLeft = UICollectionViewFlowLayout() // this is what **I would think** would be my non-nil layout
layoutLeft.itemSize = CGSize(width: 100, height: 100)
let layoutRight = UICollectionViewFlowLayout()
layoutRight.itemSize = CGSize(width: 100, height: 100)
collectionViewLeft = UICollectionView(frame: self.view.frame, collectionViewLayout: layoutLeft)
collectionViewRight = UICollectionView(frame: self.view.frame, collectionViewLayout: layoutRight)
collectionViewLeft.delegate = self
collectionViewRight.delegate = self
collectionViewLeft.dataSource = self
collectionViewRight.dataSource = self
self.view.addSubview(collectionViewLeft)
self.view.addSubview(collectionViewRight)
collectionViewLeft.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewLeftIdentifier)
collectionViewRight.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewRightIdentifier)
}
let reuseIdentifierLeft = "cellLeft" // also enter this string as the cell identifier in the storyboard
let reuseIdentifierRight = "cellRight"
var itemsRight = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"]
var itemsLeft = ["10", "20", "30", "40", "50", "60"]
// MARK: - UICollectionViewDataSource protocol
// tell the collection view how many cells to make
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == self.collectionViewLeft {
return self.itemsLeft.count
} else if collectionView == self.collectionViewRight {
return self.itemsRight.count
} else {
print("This is very bad")
assert(false, "Passed collectionView is neither collectionViewLeft nor collectionViewRight -- ruh roh!")
return 0
}
}
// make a cell for each cell index path
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == self.collectionViewLeft {
// get a reference to our storyboard cell
let cellLeft = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierLeft, for: indexPath as IndexPath) as! MyCollectionViewCell
// Use the outlet in our custom class to get a reference to the UILabel in the cell
cellLeft.myLeftLabel.text = self.itemsLeft[indexPath.item]
cellLeft.backgroundColor = UIColor.red // make cell more visible in our example project
return cellLeft
} else if collectionView == self.collectionViewRight {
let cellRight = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierRight, for: indexPath as IndexPath) as! MyRightCollectionViewCell
// Use the outlet in our custom class to get a reference to the UILabel in the cell
cellRight.myRightLabel.text = self.itemsRight[indexPath.item]
cellRight.backgroundColor = UIColor.green // make cell more visible in our example project
return cellRight
} else {
print("This is very bad")
assert(false, "Passed collectionView is neither collectionViewLeft nor collectionViewRight -- ruh roh!")
// won't actually execute the following, but to keep the compiler happy...
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierLeft, for: indexPath as IndexPath) as! MyCollectionViewCell
return cell
}
}
// MARK: - UICollectionViewDelegate protocol
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// handle tap events
if collectionView == self.collectionViewLeft {
print("You tapped cell #\(indexPath.item) on the LEFT!")
} else if collectionView == self.collectionViewRight {
print("You tapped cell #\(indexPath.item) on the RIGHT!")
} else {
print("This is very bad")
assert(false, "Passed collectionView is neither collectionViewLeft nor collectionViewRight -- ruh roh!")
}
}
}
MyCollectionViewCell.swift
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var myLeftLabel: UILabel!
}
class MyRightCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var myRightLabel: UILabel!
}
非常好 - 謝謝!我的代表不足以支持投票計數(但?),但這似乎奏效了。 – ConfusionTowers
不用擔心投票,我們大多數人都在這裏只是爲了幫助。編程祝你好運! – dive
我建議你使用隱式解包可選!而不是 ?否則你必須不斷解開觀點。如果觀點*爲*無,那麼這是一個嚴重的問題,並且沒有合理的方法可以繼續。 – Paulw11