swiftui视图开关语句导致tabview重置

发布于 2025-02-09 15:57:54 字数 1694 浏览 1 评论 0原文

我在swiftui视图中使用开关语句:

struct OnOffSwitchView: View {
    
    @ObservedObject var vm = ViewModel()
    
    var body: some View {
        switch vm.state {
        case .on:
            OnView(vm: vm)
        case .off:
            OffView(vm: vm)
        }
    }
}

@MainActor class ViewModel: ObservableObject {
    @Published var state: State = .on

    enum State {
        case on
        case off
    }
}

在儿童视图上更改viewModel状态(打开和关闭的状态相同),以便开关条件更新,呈现新视图:

struct OnView: View {
    
    @ObservedObject var vm: ViewModel
    
    var body: some View {
        VStack {
            Text("Welcome to On")
            Button { vm.state = .off }
                label: { Text("Toggle") }
        }
    }
}

这在单个视图中正常工作:

但是,当嵌套在选项卡视图中时,更改状态会导致TabView更改选项卡:

“

    TabView {
        Text("Home Tab")
            .tabItem {
                Image(systemName: "house.fill")
                Text("Home")
            }
        OnOffSwitchView()
            .tabItem {
                Image(systemName: "switch.2")
                Text("Switch")
            }
    }

有什么想法为什么会发生这种情况?我不确定(1)我的设置是否存在问题(管理状态更改),(2)我在TabView中缺少某些内容,或者(3)这是SwiftUI的问题。

该玩具示例可在

I am using a switch statement in a SwiftUI view:

struct OnOffSwitchView: View {
    
    @ObservedObject var vm = ViewModel()
    
    var body: some View {
        switch vm.state {
        case .on:
            OnView(vm: vm)
        case .off:
            OffView(vm: vm)
        }
    }
}

@MainActor class ViewModel: ObservableObject {
    @Published var state: State = .on

    enum State {
        case on
        case off
    }
}

Where the child views are changing the ViewModel state (on and off are the same) such that the switch condition updates, rendering a new view:

struct OnView: View {
    
    @ObservedObject var vm: ViewModel
    
    var body: some View {
        VStack {
            Text("Welcome to On")
            Button { vm.state = .off }
                label: { Text("Toggle") }
        }
    }
}

This works fine in a single view:

Toggle Single View

But, when nesting in a tab view, changing the state causes the TabView to change tabs:

Toggle Tab View

    TabView {
        Text("Home Tab")
            .tabItem {
                Image(systemName: "house.fill")
                Text("Home")
            }
        OnOffSwitchView()
            .tabItem {
                Image(systemName: "switch.2")
                Text("Switch")
            }
    }

Any ideas why this happening? I am unsure if (1) there is a problem with my setup (managing the state change), (2) I am missing something in the TabView, or (3) it's an issue with SwiftUI.

This toy example is available on GitHub Updated with answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听风吹 2025-02-16 15:57:54

我认为这是一个错误,因为OnoffSwitchView应被检测到相同的(默认情况下基于属性的惯例)...无论如何,explicit 选择解决了

用Xcode 13.4// iOS 15.5

struct ContentView: View {

    @State private var selection = 0

    var body: some View {
        TabView(selection: $selection) {  // << preserves selected tab !!
            Text("Home Tab")
                .tabItem {
                    Image(systemName: "house.fill")
                    Text("Home")
                }.tag(0)
            OnOffSwitchView()
                .tabItem {
                    Image(systemName: "switch.2")
                    Text("Switch")
                }.tag(1)
        }
    }
}

*注意:在这种情况下,我建议使用statebject onfoffswitchview中的视图模型。

I think it is a bug, because OnOffSwitchView should be detected identical (by default properties-based convention)... anyway introducing explicit selection solves the issue

Tested with Xcode 13.4 / iOS 15.5

struct ContentView: View {

    @State private var selection = 0

    var body: some View {
        TabView(selection: $selection) {  // << preserves selected tab !!
            Text("Home Tab")
                .tabItem {
                    Image(systemName: "house.fill")
                    Text("Home")
                }.tag(0)
            OnOffSwitchView()
                .tabItem {
                    Image(systemName: "switch.2")
                    Text("Switch")
                }.tag(1)
        }
    }
}

*Note: I would recommend in this case use StateObject for view model in OnOffSwitchView.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文