这是我的类BaseSection
实现Collection
的方式,它看起来像这样:
class BaseSection<T:Equatable> {
var items:[T]?
required init(items:[T]){
self.items = items
}
}
let sectionTop = BaseSection<TopItem>(items:["foo","bar","yo"])
let sectionBottom = BaseSection<BottomItem>(items:["foo","bar","yo"])
在此演示中,我正在构造一部分Equatable
的字符串对象,但是我的项目构造对象具有一个String
属性
此处未列出收集实现。
我需要将两个对象都放在数组中,即使它们的基类相同,也不能这样做。
let sections = [sectionTop, sectionBottom]
heterogeneous collection literal could only be inferred to '[Any]' add explicit type annotation....
我在许多解决方案上争取了数小时的努力,但在这里却无法实现我的目标。
任何帮助将不胜感激
Edit: I have uploaded the sample code to gitHub so you can get a better grasp of what im doing
答案 0 :(得分:2)
becos都是不变的,这意味着BaseSection<TopItem>
和BaseSection<BottomItem>
没有关系,因此两者的唯一共同类型是Any
,您可以点击链接在评论中以获取更多信息,作为摘要
另外,数组/字典是结构,这意味着它们是按值传递的,因此将它们视为协方差是安全的
答案 1 :(得分:2)
您似乎要构建的是一种随着数据变化自动执行表视图变化的机制。很常见的。我强烈建议您查看ListDiff,这是计算更改的有用起点。 (在我自己的代码中,我使用了重写版本的ListDiff,因此此处的示例未经测试,但应该非常接近。)
目标是创建一组更新操作(从ListDiff示例复制):
import ListDiff
extension Int : Diffable {
public var diffIdentifier: AnyHashable {
return self
}
}
let o = [0, 1, 2]
let n = [2, 1, 3]
let result = List.diffing(oldArray: o, newArray: n)
// result.hasChanges == true
// result.deletes == IndexSet(integer: 0)
// result.inserts == IndexSet(integer: 2)
// result.moves == [List.MoveIndex(from: 2, to: 0), List.MoveIndex(from: 1, to: 1)]
// result.changeCount == 4
这里重要的是您要进行一系列的删除,插入和移动操作。您可以通过以下几行将其应用于表格视图:
extension UITableView {
func applyChanges(from changeset: Result, forSection section: Int = 0) {
beginUpdates()
let deletes = changeset.deletes.map { IndexPath(row: $0, section: section) }
deleteRows(at: deletes, with: .bottom)
let inserts = changeset.deletes.map { IndexPath(row: $0, section: section) }
insertRows(at: inserts, with: .none)
for move in changeset.moves {
guard !changeset.deletes.contains(move.from) else { continue }
moveRow(at: IndexPath(row: move.from, section: section),
to: IndexPath(row: move.to, section: section))
}
endUpdates()
}
}
这里的关键是动画,您只需要索引路径。您实际上并不需要数据。因此,计算索引路径并传递它们。无需泛型。