gpt4 book ai didi

protocols - 如何将协议(protocol)定义为 @ObservedObject 属性的类型?

转载 作者:行者123 更新时间:2023-12-01 12:04:12 24 4
gpt4 key购买 nike

我有一个依赖于 View 模型的 swiftui View , View 模型有一些已发布的属性。我想为 View 模型层次结构定义一个协议(protocol)和默认实现,并使 View 依赖于协议(protocol)而不是具体类?

我希望能够编写以下内容:

protocol ItemViewModel: ObservableObject {
@Published var title: String

func save()
func delete()
}

extension ItemViewModel {
@Published var title = "Some default Title"

func save() {
// some default behaviour
}

func delete() {
// some default behaviour
}
}


struct ItemView: View {
@ObservedObject var viewModel: ItemViewModel

var body: some View {
TextField($viewModel.title, text: "Item Title")
Button("Save") { self.viewModel.save() }
}
}

// What I have now is this:

class AbstractItemViewModel: ObservableObject {
@Published var title = "Some default Title"

func save() {
// some default behaviour
}

func delete() {
// some default behaviour
}
}

class TestItemViewModel: AbstractItemViewModel {
func delete() {
// some custom behaviour
}
}

struct ItemView: View {
@ObservedObject var viewModel: AbstractItemViewModel

var body: some View {
TextField($viewModel.title, text: "Item Title")
Button("Save") { self.viewModel.save() }
}
}

最佳答案

swift 协议(protocol)和扩展中不允许使用包装器和存储属性,至少目前是这样。所以我会采用以下混合协议(protocol)、泛型和类的方法......(所有这些都可以用 Xcode 11.2/iOS 13.2 编译和测试)

// base model protocol
protocol ItemViewModel: ObservableObject {
var title: String { get set }

func save()
func delete()
}

// generic view based on protocol
struct ItemView<Model>: View where Model: ItemViewModel {
@ObservedObject var viewModel: Model

var body: some View {
VStack {
TextField("Item Title", text: $viewModel.title)
Button("Save") { self.viewModel.save() }
}
}
}

// extension with default implementations
extension ItemViewModel {

var title: String {
get { "Some default Title" }
set { }
}

func save() {
// some default behaviour
}

func delete() {
// some default behaviour
}
}

// concrete implementor
class SomeItemModel: ItemViewModel {
@Published var title: String

init(_ title: String) {
self.title = title
}
}

// testing view
struct TestItemView: View {
var body: some View {
ItemView(viewModel: SomeItemModel("test"))
}
}
backup

关于protocols - 如何将协议(protocol)定义为 @ObservedObject 属性的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59503399/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com