为什么在SwiftUI的TabView中切换选项卡时onDisappear之后再次调用onAppear? [英] Why onAppear called again after onDisappear while switching tab in TabView in SwiftUI?

查看:94
本文介绍了为什么在SwiftUI的TabView中切换选项卡时onDisappear之后再次调用onAppear?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果存在任何更改,我会在出现选项卡项时调用API.为什么在调用onDisappear之后调用onAppear?

I am calling API when tab item is appeared if there is any changes. Why onAppear called after called onDisappear?

这是简单的示例:

struct ContentView: View {
    var body: some View {
        TabView {
            NavigationView {
                Text("Home")
                    .navigationTitle("Home")
                    .onAppear {
                        print("Home appeared")
                    }
                    .onDisappear {
                        print("Home disappeared")
                    }
            }
            .tabItem {
                Image(systemName: "house")
                Text("Home")
            }.tag(0)
        
            NavigationView {
                Text("Account")
                    .navigationTitle("Account")
                    .onAppear {
                        print("Account appeared")
                    }
                    .onDisappear {
                        print("Account disappeared")
                    }
            }
            .tabItem {
                Image(systemName: "gear")
                Text("Account")
            }.tag(1)
        }
    }
}    

只需运行上面的代码,我们将在onDisappear之后看到onAppear.

Just run above code and we will see onAppear after onDisappear.

Home appeared
---After switch tab to Account---
Home disappeared
Account appeared
Home appeared

有什么解决方案可以避免这种情况吗?

Is there any solution to avoid this?

推荐答案

这是一个非常令人讨厌的错误,请想象一下这种情况: Home 视图 onAppear 方法包含一个计时器,该计时器可重复获取数据.切换到 Account 视图,会无形地触发计时器.

It's very annoying bug, imagine this scenario: Home view onAppear method contains a timer which is fetching data repeatedly. Timer is triggered invisibly by switching to the Account view.

解决方法:

  1. 为每个嵌入的 NavigationView 内容创建独立视图
  2. 将当前选择值作为 @Binding 参数传递给独立视图
  1. Create a standalone view for every embedded NavigationView content
  2. Pass the current selection value on to standalone view as @Binding parameter

例如:

struct ContentView: View {
    @State var selected: MenuItem = .HOME

    var body: some View {
        return TabView(selection: $selected) {
            HomeView(selectedMenuItem: $selected)
                .navigationViewStyle(StackNavigationViewStyle())
                .tabItem {
                    VStack {
                        Image(systemName: "house")
                        Text("Home")
                    }
                }
                .tag(MenuItem.HOME)
            
            AccountView(selectedMenuItem: $selected)
                .navigationViewStyle(StackNavigationViewStyle())
                .tabItem {
                    VStack {
                        Image(systemName: "gear")
                        Text("Account")
                    }
                }
                .tag(MenuItem.ACCOUNT)
        }
    }
}

enum MenuItem: Int, Codable {
    case HOME
    case ACCOUNT
}

HomeView:

struct HomeView: View {

    @Binding var selectedMenuItem: MenuItem

    var body: some View {
        return Text("Home")
            .onAppear(perform: {
                if MenuItem.HOME == selectedMenuItem {
                    print("-> HomeView")
                }
            })
    }
}

AccountView:

AccountView:

struct AccountView: View {

    @Binding var selectedMenuItem: MenuItem

    var body: some View {
        return Text("Account")
            .onAppear(perform: {
                if MenuItem.ACCOUNT == selectedMenuItem {
                    print("-> AccountView")
                }
            })
    }
}

这篇关于为什么在SwiftUI的TabView中切换选项卡时onDisappear之后再次调用onAppear?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆