我想基于另一个视图(LeftView)中轻击手势的动作来更新视图(RightView)。下面是我的示例代码来完成此操作:
AppState.swift
g
LeftView.swift
layer_id.slice(0, layer_id.lastIndexOf("-")) // take the part till the last -
// or, depending on the exact usecase
layer_id.slice(0, layer_id.indexOf("-", layer_id.indexOf("-"))) // take the string till the second -
// or
layer_id.match(/(\d+-\d+)/)[0] // take the first part that matches two groups of one or more chars seperated by a -
// or
layer_id.slice(0, 5) // take only the first 5 chars
RightView.swift
import Foundation
class AppState: ObservableObject {
@Published var tapCount: Int = 0
func incrementTapCount() {
self.tapCount += 1
print("tap count \(self.tapCount)")
}
}
ContentView.swift
import SwiftUI
struct LeftView: View {
@ObservedObject var appState = AppState()
var body: some View {
VStack {
Text("Left View")
}
.frame(width: 100, height: 200)
.onTapGesture {
print("tapped left view")
self.appState.incrementTapCount()
}
}
}
不幸的是,RightView文本不会随着点击数更新。但是,如果我在ObservableObject类中使用计时器来更新拍数,则RightView会正确更新。
import SwiftUI
struct RightView: View {
@ObservedObject var appState = AppState()
var body: some View {
VStack {
Text("Right View")
Text("Tap Count: \(self.appState.tapCount)")
}.frame(width: 200, height: 200)
}
}
为什么LeftView中的轻击手势不会更新RightView文本?
答案 0 :(得分:2)
LeftView
和RightView
都分别初始化各自的AppState
对象,因此它们不会观察相同的状态。
在您的两种视图中,都将@ObservedObject
保留为未初始化的属性:
LeftView.swift和RightView.swift
@ObservedObject var appState: AppState
在SwiftUI视图中具有这样的未初始化属性时,您需要在每次使用视图时为其提供一个值。
PreviewProvider
使用视图的一个实例,因此Xcode可以在画布上向您显示它,并且只需要您为appState
提供一个 placeholder 值。该值并不是很重要(除了Xcode画布,它没有在其他任何地方使用),因此您只需要提供正确类型的值即可:
#if DEBUG
struct LeftView_Previews: PreviewProvider {
static var previews: some View {
LeftView(appState: AppState())
}
}
#endif
最后在ContentView
中,您需要将对单个共享 AppState
的引用向下传递到LeftView
和RightView
,以便他们可以每个观察到相同的对象:
ContentView.swift
import SwiftUI
struct ContentView: View {
var sharedAppState = AppState()
var body: some View {
HStack {
LeftView(appState: sharedAppState)
RightView(appState: sharedAppState)
}.frame(width: 300, height: 200)
}
}
现在两个视图都在观察AppState
的相同实例,当它们的属性更改时它们都将更新。
您也可以使用@EnvironmentObject
在应用程序的所有所有视图之间共享状态,但是由于我们在这里只关注两个视图,@ObservedObject
是务实的选择