gpt4 book ai didi

ios - 使用多个 UICollectionView,出现错误, "... must be initialized with non-nil layout"

转载 作者:搜寻专家 更新时间:2023-11-01 05:56:36 26 4
gpt4 key购买 nike

我最近开始使用 Swift,我正在尝试从页面上的一个 UICollectionView(有效)增加到两个。我收到错误

"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'".

到目前为止,我在 Stack Overflow 上发现的内容已合并到我的代码中,但我仍然遇到错误。我无计可施,请帮忙!

我去过的地方:

  • 我从 this article 开始设置 UICollectionView,一切正常。
  • 现在要在同一屏幕上设置第二个 UICollectionView,我按照 this article 中的说明进行操作。 .
  • 一切似乎都很好,我收到“Build Succeeded”消息,然后在应用程序开始运行时立即崩溃。错误消息说:

*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“必须使用非零布局参数初始化 UICollectionView”

  • 在 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!

}

最佳答案

我的猜测是,您将带有空默认 init 构造函数的 UICollectionViewController 声明为变量:

var collectionViewLeft = UICollectionView()
var collectionViewRight = UICollectionView()

尝试在没有构造函数的情况下替换变量声明:

Edited code below: As @Paulw11 correctly noted in his answer below, it's better to use an implicitly unwrapped optional ! rather than ?

var collectionViewLeft: UICollectionView!
var collectionViewRight: UICollectionView!

无论如何,您在 viewDidLoad 函数中使用 UICollectionView 的指定初始化程序实例化它们。

请注意,最好在将 UICollectionView 添加为 subview 之前注册自定义类/xib。它现在并不重要,但在重构等之后可能是一个问题,因为您的代码可以在您之前调用 UICollectionView delegatedataSource 函数为单元格注册自定义类的代码。只需通过调用 self.view.addSubview() 上方的 .register() 来移动您的代码:

collectionViewLeft.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewLeftIdentifier)
collectionViewRight.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewRightIdentifier)

关于ios - 使用多个 UICollectionView,出现错误, "... must be initialized with non-nil layout",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40774046/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com