我希望动态创建一些collectionviews。
当调用我的工厂函数时,我想将其传递给UICollectionViewCell的子类类型。我正在使用类型化泛型来完成此任务。 但是,编译器使我停下脚步,并让我质疑我对Swift中多态性的理解。
有人可以阐明这件事吗?
我的CustomCell
public class DiscoverySmallCollectionCell: UICollectionViewCell {
public var mainView : DiscoveryNavigationCard
public init(image: UIImage) {
self.mainView = DiscoveryNavigationCard(largeImage: image)
super.init(frame: CGRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false
setup()
}
override public init(frame: CGRect) {
self.mainView = DiscoveryNavigationCard()
super.init(frame: CGRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false;
setup()
}
public init() {
self.mainView = DiscoveryNavigationCard()
super.init(frame: CGRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false
setup()
}
private func setup(){
self.addSubview(mainView)
pinToParent(view: mainView, parent: self)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我的控制器: 有问题的功能签名:
private func createColletionViewAndContainer <T>(identifier: String, cellSize: CGSize, cellType: T) where T: UICollectionViewCell {
呼叫功能:
private func setupCollectionViews(items: [DiscoveryItem]) {
for item in items {
let category = item.category
switch category {
case "hospital", "favourites":
self.createColletionViewAndContainer(identifier: category, cellSize: LocalLayout.smallCellSize, cellType: DiscoverySmallCollectionCell )
default :
self.createColletionViewAndContainer(identifier: category, cellSize: LocalLayout.largeCellSize, cellType: DiscoveryLargeCollectionCell)
}
}
setup()
}
答案 0 :(得分:0)
如果要使用泛型设置可重用单元格,这是一种简单的模式:
第一
设置通用单元格,在此示例中,它仅接受一个参数,但是您可以执行任何想要的操作
class GenericCollectionViewCell<U>: UICollectionViewCell {
var item: U!
}
第二
创建一个UIViewController
来接受您的通用单元格
class GenericViewController<T: GenericCollectionViewCell<U>, U>: UIViewController, UICollectionViewDelegate {
var items: [U] = []
fileprivate let cellReuseIdentifier = "GenericCollectionViewCell"
override func viewDidLoad() {
collectionView.register(T.self, forCellWithReuseIdentifier: cellReuseIdentifier)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellReuseIdentifier, for: indexPath) as? GenericCollectionViewCell<U> else { return UICollectionViewCell() }
cell.item = items[indexPath.item]
return cell
}
}
第三
子类化您的通用单元并完成所有设置
class MySublclassedCollectionViewCell: GenericCollectionViewCell<Whatever> {
override var item: Whatever! { // see that item becomes of type Whatever
didSet {
// setup your cell from here
}
}
}
最终
抢占GenericViewController
并完成工作
class SublcassedViewController: GenericViewController<GenericCollectionViewCell, Whatever> {
override func viewDidLoad() {
super.viewDidLoad()
self.items = // setup items
}
}
答案 1 :(得分:0)
在读了一些优秀的文章之后: IOS 12 Swift编程基础知识我发现了这个问题。与语法有关。
参数cellType必须为:T.Type,而不是:T。
正确的签名是:
private func createColletionViewAndContainer <T>(identifier: String, cellSize: CGSize, cellType: T.Type) where T: UICollectionViewCell {}
调用方应在cellType后面附加.self:
(signature....cellType: SomeClass.self)
因此,如果Matt Neuburg在外面:我会接受你的回答:P
非常感谢所有做出回应的人!