Ios 为什么在SwiftUI中切换TabView中的选项卡时onAppear在onDisappear之后再次调用?

Ios 为什么在SwiftUI中切换TabView中的选项卡时onAppear在onDisappear之后再次调用?,ios,swiftui,tabview,Ios,Swiftui,Tabview,如果有任何更改,我将在出现选项卡项时调用API。为什么onAppear一个接一个叫onDisappear 下面是一个简单的例子: struct ContentView: View { var body: some View { TabView { NavigationView { Text("Home") .navigationTitle("Hom

如果有任何更改,我将在出现选项卡项时调用API。为什么onAppear一个接一个叫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

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

有什么办法可以避免这种情况吗?

我不知道你为什么会在应用程序中看到这种行为。但我可以解释为什么我会在我的应用程序中看到它

我的设置与您非常相似,在iOS14测试版上运行iOS13应用程序时也看到了相同的行为。在我的主屏幕中,我有一个自定义的选项卡栏,当显示详细信息屏幕时,该选项卡栏将进行动画输入和输出。触发隐藏选项卡栏的代码在详细信息屏幕的.onAppear中完成。这将触发重新绘制主屏幕并调用.onAppear。由于这个bug和主屏幕,我删除了动画,并找到了一个更好的设置

因此,如果您的帐户屏幕中有一些内容。在主屏幕上有视觉效果的外观上,请尝试对其进行注释,看看是否解决了问题


祝你好运。

这是一个非常烦人的bug,想象一下这个场景:
Home
view
onAppear
方法包含一个重复获取数据的计时器。 通过切换到
帐户
视图,计时器以不可见的方式触发

解决方法:

  • 为每个嵌入的
    NavigationView
    内容创建独立视图
  • 将当前选择值作为
    @Binding
    参数传递到独立视图
  • 例如:

    struct ContentView:View{
    @选择的状态变量:MenuItem=.HOME
    var body:一些观点{
    返回选项卡视图(选择:$selected){
    HomeView(selectedMenuItem:$selected)
    .navigationViewStyle(StackNavigationViewStyle())
    .tabItem{
    VStack{
    图像(系统名称:“房屋”)
    文本(“主页”)
    }
    }
    .tag(MenuItem.HOME)
    AccountView(selectedMenuItem:$selected)
    .navigationViewStyle(StackNavigationViewStyle())
    .tabItem{
    VStack{
    图像(系统名称:“齿轮”)
    文本(“账户”)
    }
    }
    .tag(MenuItem.ACCOUNT)
    }
    }
    }
    枚举菜单项:Int,可编码{
    案例之家
    案例账户
    }
    
    HomeView:

    struct HomeView:View{
    @绑定变量selectedMenuItem:MenuItem
    var body:一些观点{
    返回文本(“主页”)
    .onAppear(表演:{
    如果MenuItem.HOME==selectedMenuItem{
    打印(“->HomeView”)
    }
    })
    }
    }
    
    AccountView:

    struct AccountView:View{
    @绑定变量selectedMenuItem:MenuItem
    var body:一些观点{
    返回文本(“帐户”)
    .onAppear(表演:{
    如果MenuItem.ACCOUNT==selectedMenuItem{
    打印(“->AccountView”)
    }
    })
    }
    }
    
    它可以帮助哪些人


    因为这种行为我只能在iOS 14+上重现,所以我最终在iOS 13+上使用了(只有在显示时才会正确调用;但不知道是否正确,但它可以在0.1.8版上使用)和TabView。

    您无法控制SwiftUI刷新视图的方式,最好不要依赖它。为什么需要避免出现多个
    onAppear
    ?因为嵌套视图(选项卡>导航>视图1>视图2)的初始化是在切换选项卡后刷新整个视图时调用的。为什么对我来说不是建设性的问题。。。你会考虑在你试图达到或解决的问题上重新提出你的问题,然后……也许有人会发现如何做到这一点。我不知道为什么这个问题会带来负面影响。多年来,我们一直依靠ViewWillEmerge/ViewWillEverge以某种方式工作。在iOS14测试版上运行iOS13编译的应用程序时,我也遇到了同样的问题。当打开详细信息屏幕时,会再次调用NavigationView中的.onAppear。找到解决方案了吗?这似乎仍然是iOS 14稳定版中的行为。