如果@EnvironmentObject,如何创建通用?
How to create Generic if @EnvironmentObject?
我最近发现需要编写 Class
的 Mock,因为它会导致 SwiftUI preview
无法正常工作。不幸的是,我得到了错误:
Property type 'T' does not match that of the 'wrappedValue' property of its wrapper type 'EnvironmentObject'
在视图结构中:
struct ContentView<T>: View {
@EnvironmentObject var mockFoobar: T
...
}
还有错误:
Type of expression is ambiguous without more context
对于预览结构:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let mockFoobar: MockFoobar = MockFoobar()
return ContentView<MockFoobar>()
.environmentObject(mockFoobar)
}
}
MockFoobar class 是:
class MockFoobar: ObservableObject {
...
}
正如用户@Asperi 所提供的,按照建议测试了以下内容:
class Foobar: ObservableObject {
@Published var param: Bool = false
func start() {
self.param = true
}
}
struct MyFoobarView<T: ObservableObject>: View {
@EnvironmentObject var foobar: T
var body: some View {
VStack {
Text("Hello Foobar")
}
.onAppear {
self.foobar.start()
}
}
}
struct MyFoobarView_Previews: PreviewProvider {
static var previews: some View {
let foobar: Foobar = Foobar()
return MyFoobarView()
.environmentObject(foobar)
}
}
但我收到以下错误(第一个在 .onAppear
中,第二个在 PreviewProvider 中):
Cannot call value of non-function type 'Binding<Subject>'
Generic parameter 'T' could not be inferred
EnvironmentObject必须是ObservableObject,所以这里修正
struct ContentView<T: ObservableObject>: View {
@EnvironmentObject var mockFoobar: T
// .. other code here
更新: 添加了引入模型协议的演示
protocol Foobaring {
var param: Bool { get set }
func start()
}
class Foobar: ObservableObject, Foobaring {
@Published var param: Bool = false
func start() {
self.param = true
}
}
struct MyFoobarView<T: ObservableObject & Foobaring>: View {
@EnvironmentObject var foobar: T
var body: some View {
VStack {
Text("Hello Foobar")
}
.onAppear {
self.foobar.start()
}
}
}
struct MyFoobarView_Previews: PreviewProvider {
static var previews: some View {
let foobar: Foobar = Foobar()
return MyFoobarView<Foobar>()
.environmentObject(foobar)
}
}
我最近发现需要编写 Class
的 Mock,因为它会导致 SwiftUI preview
无法正常工作。不幸的是,我得到了错误:
Property type 'T' does not match that of the 'wrappedValue' property of its wrapper type 'EnvironmentObject'
在视图结构中:
struct ContentView<T>: View {
@EnvironmentObject var mockFoobar: T
...
}
还有错误:
Type of expression is ambiguous without more context
对于预览结构:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let mockFoobar: MockFoobar = MockFoobar()
return ContentView<MockFoobar>()
.environmentObject(mockFoobar)
}
}
MockFoobar class 是:
class MockFoobar: ObservableObject {
...
}
正如用户@Asperi 所提供的,按照建议测试了以下内容:
class Foobar: ObservableObject {
@Published var param: Bool = false
func start() {
self.param = true
}
}
struct MyFoobarView<T: ObservableObject>: View {
@EnvironmentObject var foobar: T
var body: some View {
VStack {
Text("Hello Foobar")
}
.onAppear {
self.foobar.start()
}
}
}
struct MyFoobarView_Previews: PreviewProvider {
static var previews: some View {
let foobar: Foobar = Foobar()
return MyFoobarView()
.environmentObject(foobar)
}
}
但我收到以下错误(第一个在 .onAppear
中,第二个在 PreviewProvider 中):
Cannot call value of non-function type 'Binding<Subject>'
Generic parameter 'T' could not be inferred
EnvironmentObject必须是ObservableObject,所以这里修正
struct ContentView<T: ObservableObject>: View {
@EnvironmentObject var mockFoobar: T
// .. other code here
更新: 添加了引入模型协议的演示
protocol Foobaring {
var param: Bool { get set }
func start()
}
class Foobar: ObservableObject, Foobaring {
@Published var param: Bool = false
func start() {
self.param = true
}
}
struct MyFoobarView<T: ObservableObject & Foobaring>: View {
@EnvironmentObject var foobar: T
var body: some View {
VStack {
Text("Hello Foobar")
}
.onAppear {
self.foobar.start()
}
}
}
struct MyFoobarView_Previews: PreviewProvider {
static var previews: some View {
let foobar: Foobar = Foobar()
return MyFoobarView<Foobar>()
.environmentObject(foobar)
}
}