SwiftUI:点击手势切换视图

SwiftUI: On tap gesture switches views

我在使用 XCode 13.2 的项目中有以下简化代码。预期的功能是有 2 个选项卡(Tab1Tab2),并且用户能够在 Tab2 上点击屏幕以将背景从红色切换为绿色。

但是,当单击 Tab2 时,屏幕会显示选项卡 1,而不是 Tab2 并更改颜色。我想知道为什么当点击 Tab2 时应用会转到 Tab1

没有使用户转到 Tab1 的导航链接或操作。我唯一的想法是,当单击 Tab2 时,应用程序可能正在重建,这就是它返回第一个选项卡的原因?如果是这样,是否有任何好的解决方法?

注意:颜色在 Tab2 上仍然会改变,但在应用程序切换到 Tab1 之前不会。


struct ContentView: View {
    
    var body: some View {
        TabView {
            Tab1()
                .tabItem {
                    Text("Tab 1")
                }
            Tab2()
                .tabItem {
                    Text("Tab 2")
                }
        }
    }
}

struct Tab1: View {
    var body: some View {
        Text("Tab 1")
    }
}

struct Tab2: View {
    @State var isRed: Bool = false
    
    var body: some View {
        if !isRed {
            Color.green
                .onTapGesture {
                    isRed = true
                }
        } else {
            Color.red
                .onTapGesture {
                    isRed = false
                }
        }
    }
}

我注意到以这种方式使用 if/else 会导致奇怪的行为。如下所示重构 Tab2,它应该按预期工作。

struct Tab2: View {
@State var isRed: Bool = false

var body: some View {
    ZStack {
        Color.red
        Color.green
            .opacity(isRed ? 0 : 1)
    }
    .onTapGesture {
        isRed.toggle()
    }
}

}

之所以点击 Tab2 会跳回 Tab1,是因为每次点击 Tab2 的结构标识都会发生变化,导致 swiftUI 重新加载 body。见解释here。 对上面示例的一个简单修复是将整个主体包裹在 ZStack

var body: some View {
  ZStack {
    if !isRed {
      Color.green
        .onTapGesture {
          isRed = true
        }
    } else {
      Color.red
        .onTapGesture {
          isRed = false
        }
    }
  }
}