我有一个带有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外包给其他文件,或者还有其他要做的事情吗?
答案 0 :(得分: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()
中声明,则在实例化后立即将其释放。
答案 1 :(得分:0)
感谢您的帮助!我尝试了Galo的建议,但是对我来说这没有用。但是,我找到了解决方法:
您必须将委托初始化为ViewController的属性,并在其viewDidLoad函数中不!然后一切正常!
let myDataSource = MyDataSource()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MYIDENTIFIER")
collectionView.delegate = myDataSource
collectionView.dataSource = myDataSource
}
答案 2 :(得分:0)
这是另一个经常被忽视的范围问题。
val jsonObj = JSONObject("""{"hello": "world"}""")
jsonObj.getString("hello") // world