如何解决使用协议强制限制视图模型 - AssociatedType/conditional-conformance/swift 更新更新 2更新 3
protocol Identifiable {
var id: String { get }
}
struct ModelA: Identifiable {
var id: String
}
struct ModelB: Identifiable {
var id: String
}
protocol ViewModelable {
associatedtype model: Identifiable
}
struct ViewModelA: ViewModelable {
typealias model = ModelA
}
class ViewA: UIView {
var viewModel: ViewModelA
}
struct ViewModelB: ViewModelable {
typealias model = ModelB
}
class ViewB: UIView {
var viewModel: ViewModelB
}
class CustomListView: UIView {
var viewModels<T: ViewModelable>: [T]?
var viewmodels:[ViewModelable]
}
我需要对我的视图模型将持有的模型强制执行规则。但是 View1 中的语法会引发编译错误。 (协议 'ViewModelable' 只能用作通用约束,因为它具有 Self 或相关的类型要求)。那么我还有其他方法可以强制执行此操作吗?
我的用例:
自定义列表视图是一种容器视图,它将具有一个表视图并呈现视图(viewmodelA 和 viewmodelB)
解决方法
您可以在类型定义期间强制执行。
class View1<T: ViewModelable>: UIView {
var viewmodels: [T] = []
}
许多标准 API 都这样做。
Array<Element>
Dictionary<Key: Hashable etc.
更新
要通过返回 id
的所有这些协议访问您的财产,您可以这样做。
protocol ViewModelable {
associatedtype Model: Identifiable
var model: Model { get }
}
struct ViewModelA: ViewModelable {
typealias Model = ModelA
var model: Model
}
struct ViewModelB: ViewModelable {
typealias Model = ModelB
var model: Model
}
class View1<T: ViewModelable>: UIView {
var viewModels: [T] = []
func doSomething() {
let firstModelID = viewModels.first?.model.id
}
}
更新 2
自定义列表视图是一种容器视图,它将具有一个表视图并呈现视图(viewmodelA 和 viewmodelB)
class CustomListView1<A: ViewModelable,B: ViewModelable>: UIView {
var viewModelAs: [A] = []
var viewModelBs: [B] = []
}
/// You can go one step further as well
class CustomListView2<A: ViewModelable,B: ViewModelable>: UIView
where A.Model == ModelA,B.Model == ModelB {
var viewModelAs: [A] = []
var viewModelBs: [B] = []
}
更新 3
有 5 个以上的视图模型,并且所有视图模型都呈现在一个 tableview 中,因此无法将其保存在单独的数组中。
class View2: UIView {
enum ViewModel {
case viewModelA(ViewModelA)
case viewModelB(ViewModelB)
// Add as many variants as you want
var model: Identifiable {
switch self {
case .viewModelA(let vma): return vma.model
case .viewModelB(let vmb): return vmb.model
}
}
}
var viewModels: [ViewModel] = []
func doSomething() {
let firstModelID = viewModels.first?.model.id
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。