首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI ObservedObject Binding KeyPath下标错误

SwiftUI ObservedObject Binding KeyPath下标错误
EN

Stack Overflow用户
提问于 2019-09-18 11:47:14
回答 1查看 1.1K关注 0票数 2

尝试使用泛型类型T的KeyPath在@ObservedObject的属性上指定绑定时,遇到编译器错误。

我正在尝试创建一个通用的SwiftUI视图,它将适用于具有相同类型的多个属性的类。SwiftUI视图需要是泛型的;但是,我无法确定如何创建到通过KeyPath访问的主对象的属性的绑定。下面的代码返回错误“类型为'T‘的值没有下标”

更新:我发现了代码中的错误,而不是$modelkeyPath: kp。我应该使用$modeldynamicMember: kp。

代码语言:javascript
复制
import SwiftUI

class TestClass: ObservableObject {
    @Published public var str1: String = "one"
    @Published public var str2: String = "two"
}

struct ContentView: View { 

    @ObservedObject var test = TestClass()
    var body: some View {
        VStack {
            HStack{
                Text("String One").padding(20)
                StringView(model: test, kp: \TestClass.str1).padding(20)
            }
            HStack{
                Text("String Two").padding(20)
                StringView(model: test, kp: \TestClass.str2).padding(20)
            }
        }
    }
}

struct StringView<T>: View where T: ObservableObject {

    @ObservedObject var model: T

    var kp: ReferenceWritableKeyPath<T,String>

    init(model: T, kp: ReferenceWritableKeyPath<T,String>) {
        self.model = model
        self.kp = kp
    }

    var body: some View {
        HStack{
        TextField("String", text: $model[keyPath: kp])   <--- COMPILER ERROR HERE
        Text(model[keyPath: kp])
        }
    }
}

有可能做到这一点吗?

EN

回答 1

Stack Overflow用户

发布于 2019-09-18 14:47:06

我认为你可以用下面的代码来做。但我的想法有点冗长。

至少,TextField需要绑定器。所以KeyPath的目标类型应该是这样的。

代码语言:javascript
复制
class TestClass: ObservableObject {
  @Published public var str1: String = "one"
  @Published public var str2: String = "two"
}

struct _ContentView: View {

  @ObservedObject var test = TestClass()

  init() {

  }
  var body: some View {
    VStack {
      HStack{
        Text("String One").padding(20)
        StringView(model: test, kp: \ObservedObject<TestClass>.Wrapper.str1).padding(20)
      }
      HStack{
        Text("String Two").padding(20)
        StringView(model: test, kp: \ObservedObject<TestClass>.Wrapper.str2).padding(20)
      }
    }
  }
}

struct StringView<T>: View where T: ObservableObject {

  @ObservedObject var model: T

  var kp: ReferenceWritableKeyPath<ObservedObject<T>.Wrapper, Binding<String>>

  init(model: T, kp: ReferenceWritableKeyPath<ObservedObject<T>.Wrapper, Binding<String>>) {
    self.model = model
    self.kp = kp
  }

  var body: some View {
    HStack{
      TextField("String", text: $model[keyPath: kp])
      Text($model[keyPath: kp].wrappedValue)
    }
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57984819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档