我已经将我与UICollectionViewCells的工作重构为以下内容
struct CollectionViewCellModel<T: UICollectionViewCell> {
let reuseIdentifier: NSString
let allowsSelection: Bool
// Optional callbacks
var onCreate: ((T) -> Void)? = nil
var onSelection: ((T) -> Void)? = nil
var onWillBeDisplayed: ((T) -> Void)? = nil
var onDelete: ((T) -> Void)? = nil
// Create cell
func toCell(collectionView: UICollectionView, indexPath: NSIndexPath) -> T {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as T
if let onCreate = onCreate { onCreate(cell) }
return cell
}
}这使得我更容易创建一个特定单元格的列表(比如表单),然后使用它们。
然而,在如何存储这些对象时,我总是会被绊倒。我不能将它们降到CollectionViewCellModel<UICollectionViewCell>,因此不能存储[CollectionViewCellModel<UICollectionViewCell>的列表
我以为斯威夫特支持向下投射,但显然不是一般类型的?
let cell = CollectionViewCellModel<A>(...)
let genericCell = cell as CollectionViewCellModel<UICollectionViewCell>
// ERROR: UICollectionViewCell is not identical to A
let genericMaybeCell = cell as? CollectionViewCellModel<UICollectionViewCell>
// ERROR: UICollectionViewCell is not identical to A我是否必须将它们存储为一个Any数组,然后每次都进行转换,还是我只是误解了一些事情(或者两者兼而有之)?
更新:我在操场上做了一些工作,清楚地说明了我的意思:
protocol IA {
func name() -> String
}
class A:IA { func name() -> String { return "A (Base)" } }
class B: A { override func name() -> String { return "B (Child of A)" } }
class C: B { override func name() -> String { return "C (Child of B)" } }
struct SA<T: A> {
}
let struct0: Any = SA<B>()
// OK: yes, the struct of B is an Any!
// but since B inherits from A, isn't it safe to
// say that SA<B> is also of type SA<A>?
let struct1: SA<A> = SA<B>() as SA<A>
// NO
// ERROR: 'B' is not identical to 'A'
let struct1Optional: SA<A> = SA<B>() as? SA<A>
// not even optionally? NO
// ERROR: 'B' is not identical to 'A'我想这是不可能的。也许在斯威夫特1.3。请参阅注释中的线程。
最新情况(2/17/15)
对于那些对我为什么要这么做感兴趣的人来说,首先,你必须了解我是如何使用我的CollectionViewControllers (CVCs)的。我已经抽象出一个基本的CVC来执行每个屏幕需要的通用方法。这个CVC有一个协议,它需要一个Factory来创建CVC模型。这些模型知道如何转换自己,响应动作,并且非常像一个控制器。他们很胖而且很活跃。另一方面,我的观点都是愚蠢的。他们所知道的就是在屏幕上移动东西,或者进入不同的显示状态。当从CVC配置单元格时,您最终会执行这些大开关语句,从可读性的角度来看,这些语句实际上并没有告诉您多少期望“路由此”。更糟糕的是,您开始在其中配置视图。这并不可怕,但总的来说--对我来说--一个视图控制器控制着它所负责的视图。虽然这个VC可能是单元的父VC,但这并没有赋予它适当的权限来对其进行大量操作。这让你的VC做一些像cell.changeDisplayToActiveState()这样的事情;简而言之,它现在承担着控制自己的孩子细胞的负担。这就是所有“胖”风投的贡献所在。我首先选择通过采用VIPER模式来偏离这一路径,但我发现它过分了--特别是对于一个新的项目。我放弃了它,开始在一个基地CVC工作。目前,我的项目就是这样工作的:
vc.changeDisplayState(...)或changeToVc(...) )中调用视图控制器的公共函数。发布于 2015-02-14 06:58:30
我不知道你到底在找什么,但我会尽力回答的。想必你对为某些特定的CollectionViewCellModel<X>存储一堆X不感兴趣,因为“我如何存储它们?”的答案很简单:[CollectionViewCellModel<X>]。因此,我猜您想要一个--您想要一个用于异构T的CollectionViewCellModel<T>数组。实现这一点的最好方法是给您的CollectionViewCellModel<T>提供一个公共协议(或基类,但在您的情况下,它们是struct的,而不是那样的),大致如此:
protocol CollectionViewCellModelType {
var reuseIdentifier: NSString {get}
var allowsSelection: Bool {get}
func toCell(
collectionView: UICollectionView, indexPath: NSIndexPath
) -> UICollectionViewCell
}
struct CollectionViewCellModel<T: UICollectionViewCell>
: CollectionViewCellModelType {
let reuseIdentifier: NSString
let allowsSelection: Bool
// Optional callbacks
var onCreate: ((T) -> Void)? = nil
var onSelection: ((T) -> Void)? = nil
var onWillBeDisplayed: ((T) -> Void)? = nil
var onDelete: ((T) -> Void)? = nil
// Create cell
func toCell(
collectionView: UICollectionView, indexPath: NSIndexPath
) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(
reuseIdentifier, forIndexPath: indexPath) as! T
if let onCreate = onCreate { onCreate(cell) }
return cell
}
}
var a: [CollectionViewCellModelType] = [] // put them in here希望这能帮上忙
戴夫
https://stackoverflow.com/questions/28503963
复制相似问题