EquatableView 不强制 SwiftUI 使用 == 函数的自定义实现
EquatableView not forcing SwiftUI to use custom implementation of the == function
我无法按照文章使用 EquatableView:Link1 and link2。我希望每次单击按钮时都会调用 TestView 中的“==”函数。
我是不是漏掉了什么?
struct ContentView: View {
@State var state = false
var body: some View {
VStack {
EquatableView(content: TestView(state: $state))
Button("Change state", action: {state.toggle()})
}
}
}
struct TestView: View, Equatable {
@Binding var state: Bool
var body: some View {
let _ = print("Test updated")
Text("TestView state : \(state.description)")
}
static func == (lhs: TestView, rhs: TestView) -> Bool {
//Never printed or invoked
let _ = print ("lhs == rhs invoked \(lhs.state) == \(rhs.state)")
return lhs.state == rhs.state
}
}
更新:
在 Alperen 的非常有帮助的回复之后,它表明必须添加“@State”才能触发 ==。但是,如下所示,将“@State”变量从父级直接传递到子视图的“@State”以获得相同的变量,这是没有意义的。
因此,我向 TestView 添加了另一个变量“@State var notUsed”,它将不起作用 除非“@Binding”被删除。人们还想比较“@Binding”变量,所以对我来说这是不合逻辑的。
我的问题仍然存在,我是不是遗漏了什么或者这种行为是设计使然的?
该代码有效。你能试试这个吗?
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ContentView: View {
@State var state = false
var body: some View {
VStack {
TestView(state: state).equatable()
Button("Not Change", action: {})
Button("Change", action: {state.toggle()})
}
}
}
struct TestView: View, Equatable {
@State var state: Bool
var body: some View {
let _ = print("Test updated")
Text("TestView state : \(state.description)")
}
static func == (lhs: TestView, rhs: TestView) -> Bool {
//Never printed or invoked
let _ = print ("lhs == rhs invoked \(lhs.state) == \(rhs.state)")
return lhs.state == rhs.state
}
}
Equatable
在创建视图时使用,因此它要么替换已经存在的,要么不替换。在你的例子中 TestView
没有被重新创建,因为它不应该在绑定上改变 - 只有 body
用新值呈现。
模拟游戏(测试用)最简单的就是添加条件。 Equatibility 只是一种优化技术,它可以帮助 SwiftUI 检测是否替换现有视图实例。
这里是演示 Equatable 作品的更新示例。使用 Xcode 12.1 / iOS 14.1
测试
struct ContentView: View {
@State var state = false
var body: some View {
VStack {
if state {
EquatableView(content: TestView(state: $state))
}
Button("Change state", action: {state.toggle()})
}
}
}
struct TestView: View, Equatable {
@Binding var state: Bool
init(state: Binding<Bool>) {
_state = state
print(">> inited") // << check if created
}
var body: some View {
let _ = print("Test updated")
Text("TestView state : \(state.description)")
}
static func == (lhs: TestView, rhs: TestView) -> Bool {
//Never printed or invoked
let _ = print ("lhs == rhs invoked \(lhs.state) == \(rhs.state)")
return lhs.state == rhs.state
}
}
我无法按照文章使用 EquatableView:Link1 and link2。我希望每次单击按钮时都会调用 TestView 中的“==”函数。
我是不是漏掉了什么?
struct ContentView: View {
@State var state = false
var body: some View {
VStack {
EquatableView(content: TestView(state: $state))
Button("Change state", action: {state.toggle()})
}
}
}
struct TestView: View, Equatable {
@Binding var state: Bool
var body: some View {
let _ = print("Test updated")
Text("TestView state : \(state.description)")
}
static func == (lhs: TestView, rhs: TestView) -> Bool {
//Never printed or invoked
let _ = print ("lhs == rhs invoked \(lhs.state) == \(rhs.state)")
return lhs.state == rhs.state
}
}
更新:
在 Alperen 的非常有帮助的回复之后,它表明必须添加“@State”才能触发 ==。但是,如下所示,将“@State”变量从父级直接传递到子视图的“@State”以获得相同的变量,这是没有意义的。
因此,我向 TestView 添加了另一个变量“@State var notUsed”,它将不起作用 除非“@Binding”被删除。人们还想比较“@Binding”变量,所以对我来说这是不合逻辑的。
我的问题仍然存在,我是不是遗漏了什么或者这种行为是设计使然的?
该代码有效。你能试试这个吗?
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct ContentView: View {
@State var state = false
var body: some View {
VStack {
TestView(state: state).equatable()
Button("Not Change", action: {})
Button("Change", action: {state.toggle()})
}
}
}
struct TestView: View, Equatable {
@State var state: Bool
var body: some View {
let _ = print("Test updated")
Text("TestView state : \(state.description)")
}
static func == (lhs: TestView, rhs: TestView) -> Bool {
//Never printed or invoked
let _ = print ("lhs == rhs invoked \(lhs.state) == \(rhs.state)")
return lhs.state == rhs.state
}
}
Equatable
在创建视图时使用,因此它要么替换已经存在的,要么不替换。在你的例子中 TestView
没有被重新创建,因为它不应该在绑定上改变 - 只有 body
用新值呈现。
模拟游戏(测试用)最简单的就是添加条件。 Equatibility 只是一种优化技术,它可以帮助 SwiftUI 检测是否替换现有视图实例。
这里是演示 Equatable 作品的更新示例。使用 Xcode 12.1 / iOS 14.1
测试struct ContentView: View {
@State var state = false
var body: some View {
VStack {
if state {
EquatableView(content: TestView(state: $state))
}
Button("Change state", action: {state.toggle()})
}
}
}
struct TestView: View, Equatable {
@Binding var state: Bool
init(state: Binding<Bool>) {
_state = state
print(">> inited") // << check if created
}
var body: some View {
let _ = print("Test updated")
Text("TestView state : \(state.description)")
}
static func == (lhs: TestView, rhs: TestView) -> Bool {
//Never printed or invoked
let _ = print ("lhs == rhs invoked \(lhs.state) == \(rhs.state)")
return lhs.state == rhs.state
}
}