扩展 UICollectionViewDataSource 协议以添加默认实现
Extend UICollectionViewDataSource Protocol to add default implementations
我有一个相当大的应用程序,它有很多集合视图。大多数集合视图对数据源和流布局委托具有相同的实现(相同的大小、边距等)。我正在尝试创建一个协议,它提供 UICollectionViewDataSource 和 UICollectionViewDelegateFlowLayout 的默认实现。这是我的代码。
protocol TiledCollectionView{}
extension UICollectionViewDataSource where Self: TiledCollectionView{
//default implementation of the 3 methods to load the data ...
}
extension UICollectionViewDelegateFlowLayout where Self: TiledCollectionView {
//default implementation for layout methods to set default margins etc...
}
class MyViewController: UIViewController, TiledCollectionView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
// the rest of the required logic for view controller
// here I Don't implement any CollectionView methods since I have provided the default implementation already
}
问题是,编译器抱怨 MyViewController 不符合 UICollectionViewDataSource。这不应该是这种情况,因为我明确表示,如果类型是 TiledCollectionView,则添加默认实现。
有人可以帮忙吗?
我知道这不完全是你问的,我试过了 - 它没有用。现在正在寻找可能的答案,因为有类似的情况。但我可以为您提供这样的选项,即如何在您的自定义协议中隐藏 delegate/dataSource 实现的所有逻辑。
class CollectionViewProtocolHandler: NSObject, UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 0
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return UICollectionViewCell() // only for test
}
}
protocol CollectionViewProtocol {
var handler: CollectionViewProtocolHandler! {get set}
mutating func useProtocolForCollectionView(collectionView: UICollectionView)
}
extension CollectionViewProtocol {
mutating func useProtocolForCollectionView(collectionView: UICollectionView) {
handler = CollectionViewProtocolHandler()
collectionView.delegate = handler
collectionView.dataSource = handler
}
}
class ViewController: UIViewController, CollectionViewProtocol {
var handler: CollectionViewProtocolHandler! // CollectionViewProtocol convenience
override func viewDidLoad() {
super.viewDidLoad()
let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: UICollectionViewFlowLayout())
collectionView.backgroundColor = .redColor()
view.addSubview(collectionView)
var reference = self
reference.useProtocolForCollectionView(collectionView) // for initialize protocol
}
}
我预计问题在于这是一个 Objective-C 协议。 Objective-C 从未听说过协议扩展。因此它不知道此协议扩展正在向 MyClass 注入两个函数。它看不到它们,所以就它而言,不满足协议要求。
要添加但修改 katleta3000 回答的内容,您可以限制协议仅适用于 'class'
CollectionViewProtocol : class
这样你就不需要 'useProtocolForCollectionView:'
成为 mutating
这样你就不需要 var reference = self
你可以直接说 self.userProtocolForCollectionView(collectionView)
特别是如果您只打算使用 NSObject 或 class 类型(UIViewController、UICollectionView 等)实现此协议
我有一个相当大的应用程序,它有很多集合视图。大多数集合视图对数据源和流布局委托具有相同的实现(相同的大小、边距等)。我正在尝试创建一个协议,它提供 UICollectionViewDataSource 和 UICollectionViewDelegateFlowLayout 的默认实现。这是我的代码。
protocol TiledCollectionView{}
extension UICollectionViewDataSource where Self: TiledCollectionView{
//default implementation of the 3 methods to load the data ...
}
extension UICollectionViewDelegateFlowLayout where Self: TiledCollectionView {
//default implementation for layout methods to set default margins etc...
}
class MyViewController: UIViewController, TiledCollectionView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
// the rest of the required logic for view controller
// here I Don't implement any CollectionView methods since I have provided the default implementation already
}
问题是,编译器抱怨 MyViewController 不符合 UICollectionViewDataSource。这不应该是这种情况,因为我明确表示,如果类型是 TiledCollectionView,则添加默认实现。
有人可以帮忙吗?
我知道这不完全是你问的,我试过了 - 它没有用。现在正在寻找可能的答案,因为有类似的情况。但我可以为您提供这样的选项,即如何在您的自定义协议中隐藏 delegate/dataSource 实现的所有逻辑。
class CollectionViewProtocolHandler: NSObject, UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 0
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return UICollectionViewCell() // only for test
}
}
protocol CollectionViewProtocol {
var handler: CollectionViewProtocolHandler! {get set}
mutating func useProtocolForCollectionView(collectionView: UICollectionView)
}
extension CollectionViewProtocol {
mutating func useProtocolForCollectionView(collectionView: UICollectionView) {
handler = CollectionViewProtocolHandler()
collectionView.delegate = handler
collectionView.dataSource = handler
}
}
class ViewController: UIViewController, CollectionViewProtocol {
var handler: CollectionViewProtocolHandler! // CollectionViewProtocol convenience
override func viewDidLoad() {
super.viewDidLoad()
let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: UICollectionViewFlowLayout())
collectionView.backgroundColor = .redColor()
view.addSubview(collectionView)
var reference = self
reference.useProtocolForCollectionView(collectionView) // for initialize protocol
}
}
我预计问题在于这是一个 Objective-C 协议。 Objective-C 从未听说过协议扩展。因此它不知道此协议扩展正在向 MyClass 注入两个函数。它看不到它们,所以就它而言,不满足协议要求。
要添加但修改 katleta3000 回答的内容,您可以限制协议仅适用于 'class'
CollectionViewProtocol : class
这样你就不需要 'useProtocolForCollectionView:'
成为 mutating
这样你就不需要 var reference = self
你可以直接说 self.userProtocolForCollectionView(collectionView)
特别是如果您只打算使用 NSObject 或 class 类型(UIViewController、UICollectionView 等)实现此协议