不能在额外的类中外包 UICollectionViewDatasource
Posted
技术标签:
【中文标题】不能在额外的类中外包 UICollectionViewDatasource【英文标题】:Can not outsource UICollectionViewDatasource in extra class 【发布时间】:2019-02-04 19:19:12 【问题描述】:我有一个带有 CollectionView 的 ViewController,并且想将 UICollectionViewDataSource 放在一个额外的类中,以便可以重用它。 (我没有使用界面生成器)。
因此,我创建了一个额外的类:
class MyDataSource: NSObject, UICollectionViewDelegate, UICollectionViewDataSource
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 5
public func numberOfSections(in collectionView: UICollectionView) -> Int
return 1
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MYIDENTIFIER", for: indexPath)
cell.backgroundColor = .blue
return cell
在带有 CollectionView 的 ViewController 中,我设置了它:
override func viewDidLoad()
super.viewDidLoad()
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MYIDENTIFIER")
let myDataSource = MyDataSource()
collectionView.delegate = myDataSource
collectionView.dataSource = myDataSource
但是,collectionView 将保持为空 - 上面没有单元格。
但是,如果我将所有 DataSource 函数放入 ViewController 类本身并将委托和 DataSource 设置为 self,那么一切正常。
是否不能将 UICollectionViewDataSource 外包到其他文件中,或者您还有什么需要做的吗?
【问题讨论】:
我认为你必须用collectionView初始化数据源。在你的 dataSource 类中创建一个init(collectionView: UICollectionView)
init
@GaloTorresSevilla 它应该如何提供帮助?
@AndreyChernukha 它将使用 collectionView 初始化数据源。然后在 dataSource 类中设置collectionView.dataSource = self
。我就是这样做的,而且效果很好。
@GaloTorresSevilla 所做的与您的建议之间的实际区别是什么?无论哪种方式,集合视图都接收数据源
真的不确定。这就是为什么我说我认为。我会试着找出答案
【参考方案1】:
以防万一。这就是我所说的调用 init 方法的原因。 @Andrey Chernukha,如果造成任何混乱,抱歉。这就是为什么我说它适用于 init
但我想这与 Pascal 的原因相同
import UIKit
class ViewController: UIViewController
lazy var collectionView : UICollectionView =
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .green
return cv
()
var dataSource : CustomDataSource!
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.addSubview(collectionView)
collectionView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
dataSource = CustomDataSource(collectionView: collectionView)
class CustomDataSource : NSObject, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate
let collectionView : UICollectionView
init(collectionView: UICollectionView)
self.collectionView = collectionView
super.init()
self.collectionView.dataSource = self
self.collectionView.delegate = self
self.collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 3
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = .red
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: 100, height: 100)
class Cell : UICollectionViewCell
override init(frame: CGRect)
super.init(frame: frame)
setupViews()
func setupViews()
self.backgroundColor = .red
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
我对其进行了测试,原因是 dataSource
在 collectionView 中很弱,因此如果在 viewDidLoad()
中声明,它会在实例化后立即解除分配
【讨论】:
【参考方案2】:感谢您的帮助!我尝试了 Galo 的建议,但对我来说这不起作用。但是,我找到了解决方案:
您必须将委托初始化为 ViewController 的属性,并且 不要 在其 viewDidLoad 函数中!然后一切正常!
let myDataSource = MyDataSource()
override func viewDidLoad()
super.viewDidLoad()
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MYIDENTIFIER")
collectionView.delegate = myDataSource
collectionView.dataSource = myDataSource
【讨论】:
【参考方案3】:这是另一个经常被忽视的范围问题。
override func viewDidLoad()
super.viewDidLoad()
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MYIDENTIFIER")
let myDataSource = MyDataSource(). //See the problem here?
collectionView.delegate = myDataSource
collectionView.dataSource = myDataSource
//myDataSource will be released!
【讨论】:
以上是关于不能在额外的类中外包 UICollectionViewDatasource的主要内容,如果未能解决你的问题,请参考以下文章