I have a generic class named GenericView<Key: Equatable>
which conforms to UICollectionViewDelegateFlowLayout
protocol and holds a collectionview. Then I have a NewView
class inherits from GenericView<Key: Equatable>
.
The problem is, delegate methods implemented within NewView
class never get called if they doesn't exist in GenericView<Key: Equatable>
. UIScrollView delegate methods never get called as well, unless they has an @objc
prefix. However, the @objc
prefix doesn't solve the UICollectionView delegate issue.
Simple Code:
// 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)")
}
}
Although UICollectionViewDelegateFlowLayout
inherits from UIScrollViewDelegate
, they have different behaviors in the above code.
I find this: https://bugs.swift.org/browse/SR-2817 . The bug was reported in 2016.
It seems that this is not a UICollectionView
issue, but a issue which exists in Swift and Objective-C interaction.
I wonder if this is an issue which will be solved in the future, or it's a feature and I should prevent writing code in this way. This really confuses me and wastes lots of time. Generic type is a great idea and is widely used in programming.
The problem is UICollectionViewDelegateFlowLayout
delegated are being set to the delegates of GenericView
. But NewView
has another set of methods which are not confirmed to UICollectionViewDelegateFlowLayout
of the collectionView
. To make it work you need to add prefix override
in front of the UICollectionViewDelegateFlowLayout
methods in NewView
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.