如何return查看编辑其属性?
How to return View for editing its property?
我正在制作 class 其编辑器视图 returns。
但是报错
Cannot convert value of type 'Published.Publisher' to expected
argument type 'Binding'
这是 Playgrounds 的简单测试代码。
import SwiftUI
import PlaygroundSupport
struct EditorView: View {
@Binding var text: String
var body: some View {
HStack {
Text("Name:")
TextField("Jerry", text: $text)
}
}
}
class MyModel: ObservableObject {
@Published var name: String = "Tom"
func editorView() -> some View {
EditorView(text: $name) // [ERROR] Cannot convert value of type 'Published.Publisher' to expected argument type 'Binding<String>'
}
}
struct ContentView: View {
@StateObject var model: MyModel = .init()
var body: some View {
model.editorView()
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
.previewLayout(.fixed(width: 375, height: 400))
}
}
let viewController = UIHostingController(rootView: ContentView())
let nav = UINavigationController(rootViewController: viewController)
PlaygroundPage.current.liveView = nav
怎么了?
2022.03.23 添加
我测试了不绑定的视图,可以。我认为 class 可以用它的 属性 创建一个视图。但是不能通过@Binding.
import SwiftUI
import PlaygroundSupport
struct EditorView: View {
@Binding var text: String
var body: some View {
HStack {
Text("Name:")
TextField("Jerry", text: $text)
}
}
}
// Just display the name parameter
struct DispView: View {
let name: String
var body: some View {
Text(name)
}
}
class MyModel: ObservableObject {
@Published var name: String = "Tom"
@ViewBuilder
func editorView() -> some View {
// EditorView(text: $name) // Error at this line.
DispView(name: name) // Pass the property.
}
}
struct ContentView: View {
@StateObject var model: MyModel = .init()
var body: some View {
model.editorView()
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
.previewLayout(.fixed(width: 375, height: 400))
}
}
let viewController = UIHostingController(rootView: ContentView())
let nav = UINavigationController(rootViewController: viewController)
PlaygroundPage.current.liveView = nav
绑定由 StateObject
包装器(在 ObservableObject
上)提供,视图应在 body
中创建(即在视图层次结构中),因此它应该看起来像
struct ContentView: View {
@StateObject var model: MyModel = .init()
var body: some View {
EditorView(text: model.$name) // << here !!
}
}
注意: 替代方法是让 EditorView
直接依赖于 MyModel
,然后在这样的视图中你可以创建一个包装器来提供所需的绑定.
您在错误的位置创建了 EditorView,将它放在您的 ContentView
而不是您的 ViewModel 中。 ViewModel 用于保存数据(或模型)而不是 View。我认为 SwiftUI 不是为携带视图而设计的。
struct ContentView: View {
@StateObject var model: MyModel = .init()
var body: some View {
editorView
}
}
extension ContentView {
@ViewBuilder
var editorView: some View {
EditorView(text: $model.name)
}
}
如果您仍想将它放在您的 ViewModel 中,这应该是工作代码。您可以创建新的绑定作为视图初始化程序的参数。
@ViewBuilder
func editorView() -> some View {
EditorView(text:
Binding { name } set: { newName in self.name = newName }
)
}
我正在制作 class 其编辑器视图 returns。 但是报错
Cannot convert value of type 'Published.Publisher' to expected argument type 'Binding'
这是 Playgrounds 的简单测试代码。
import SwiftUI
import PlaygroundSupport
struct EditorView: View {
@Binding var text: String
var body: some View {
HStack {
Text("Name:")
TextField("Jerry", text: $text)
}
}
}
class MyModel: ObservableObject {
@Published var name: String = "Tom"
func editorView() -> some View {
EditorView(text: $name) // [ERROR] Cannot convert value of type 'Published.Publisher' to expected argument type 'Binding<String>'
}
}
struct ContentView: View {
@StateObject var model: MyModel = .init()
var body: some View {
model.editorView()
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
.previewLayout(.fixed(width: 375, height: 400))
}
}
let viewController = UIHostingController(rootView: ContentView())
let nav = UINavigationController(rootViewController: viewController)
PlaygroundPage.current.liveView = nav
怎么了?
2022.03.23 添加
我测试了不绑定的视图,可以。我认为 class 可以用它的 属性 创建一个视图。但是不能通过@Binding.
import SwiftUI
import PlaygroundSupport
struct EditorView: View {
@Binding var text: String
var body: some View {
HStack {
Text("Name:")
TextField("Jerry", text: $text)
}
}
}
// Just display the name parameter
struct DispView: View {
let name: String
var body: some View {
Text(name)
}
}
class MyModel: ObservableObject {
@Published var name: String = "Tom"
@ViewBuilder
func editorView() -> some View {
// EditorView(text: $name) // Error at this line.
DispView(name: name) // Pass the property.
}
}
struct ContentView: View {
@StateObject var model: MyModel = .init()
var body: some View {
model.editorView()
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
.previewLayout(.fixed(width: 375, height: 400))
}
}
let viewController = UIHostingController(rootView: ContentView())
let nav = UINavigationController(rootViewController: viewController)
PlaygroundPage.current.liveView = nav
绑定由 StateObject
包装器(在 ObservableObject
上)提供,视图应在 body
中创建(即在视图层次结构中),因此它应该看起来像
struct ContentView: View {
@StateObject var model: MyModel = .init()
var body: some View {
EditorView(text: model.$name) // << here !!
}
}
注意: 替代方法是让 EditorView
直接依赖于 MyModel
,然后在这样的视图中你可以创建一个包装器来提供所需的绑定.
您在错误的位置创建了 EditorView,将它放在您的 ContentView
而不是您的 ViewModel 中。 ViewModel 用于保存数据(或模型)而不是 View。我认为 SwiftUI 不是为携带视图而设计的。
struct ContentView: View {
@StateObject var model: MyModel = .init()
var body: some View {
editorView
}
}
extension ContentView {
@ViewBuilder
var editorView: some View {
EditorView(text: $model.name)
}
}
如果您仍想将它放在您的 ViewModel 中,这应该是工作代码。您可以创建新的绑定作为视图初始化程序的参数。
@ViewBuilder
func editorView() -> some View {
EditorView(text:
Binding { name } set: { newName in self.name = newName }
)
}