UICollectionView 委托方法在从泛型类继承时从未调用



我有一个名为GenericView<Key: Equatable>的泛型类,它符合UICollectionViewDelegateFlowLayout协议并持有集合视图。然后我有一个从GenericView<Key: Equatable>继承的NewView类。

问题是,如果在类中不存在委托方法,则NewView类中实现的委托方法永远不会被调用GenericView<Key: Equatable>。UIScrollView 委托方法也永远不会被调用,除非它们具有@objc前缀。但是,@objc前缀并不能解决 UICollectionView 委托问题。

简单代码:

// MARK: - Generic Class
class GenericView<Key: Equatable>: UIView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var key: Key?
var collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
override init(frame: CGRect) {
super.init(frame: frame)
// Constraint collection view.
collectionView.translatesAutoresizingMaskIntoConstraints = false
addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.leadingAnchor.constraint(equalTo: leadingAnchor),
collectionView.topAnchor.constraint(equalTo: topAnchor),
collectionView.trailingAnchor.constraint(equalTo: trailingAnchor),
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
// Set delegate and data source.
collectionView.delegate  = self
collectionView.dataSource = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
cell.contentView.backgroundColor = .blue
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 100)
}
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
print("generic class: (#function)")
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("generic class: (#function)")
}
}
// MARK: - SubClass
class NewView: GenericView<String> {
// called
override func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
print("new class: (#function)")
}
// called
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("new class: (#function)")
}
// called
@objc func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("new class: (#function)")
}
// not called
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("new class: (#function)")
}
// not called
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
print("new class: (#function)")
}
// not called
@objc func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print("new class: (#function)")
}
}

虽然UICollectionViewDelegateFlowLayout继承自UIScrollViewDelegate,但它们在上面的代码中有不同的行为。

我发现这个:https://bugs.swift.org/browse/SR-2817.该错误于 2016 年报告。

这似乎不是一个UICollectionView的问题,而是存在于 Swift 和 Objective-C 交互中的问题。

我想知道这是否是一个将来会解决的问题,或者它是一个功能,我应该防止以这种方式编写代码。这真的让我感到困惑并浪费了很多时间。泛型类型是一个好主意,广泛用于编程。

问题是UICollectionViewDelegateFlowLayout委派正在设置为GenericView的委托。但是NewView还有另一套方法没有得到UICollectionViewDelegateFlowLayoutcollectionView的证实。要使其正常工作,您需要在NewView中的UICollectionViewDelegateFlowLayout方法前面添加前缀override

最新更新