iOS14.2中的SwiftUI PageTabView会多次调用ChildView的onAppear方法

Wer*_*erb 7 uitabview ios swiftui ios14

我使用 TabView PageTabViewStyle 和 SwiftUI 来显示页面视图,当我滑动这个 TabView 时,我发现子视图会多次调用 onAppear 方法,有人可以告诉我为什么吗?

这是我的代码

import SwiftUI

struct Pageview: View {
    
    @StateObject var vm = PageViewModel()
    
    var body: some View {
        VStack {
            
            DragViewBar().padding(.top, 14)
            
            TabView(selection: $vm.selectTabIndex) {
                
                TextView(index: "0").tag(0)
                TextView(index: "1").tag(1)
                TextView(index: "2").tag(2)
                TextView(index: "3").tag(3)
                TextView(index: "4").tag(4)
                TextView(index: "5").tag(5)
                
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            
        }

    }
}

struct TextView: View {
    
    let index: String
    
    var body: some View {
        VStack {
            Text(index)
        }
        .onAppear { print(index) }
        
    }
}

struct DragViewBar: View {
    var body: some View {
        Rectangle()
            .frame(width:36.0,height:5.0).foregroundColor(Color.blue)
            .cornerRadius(100)
    }
}

class PageViewModel: ObservableObject {
    @Published var selectTabIndex = 0
}

Run Code Online (Sandbox Code Playgroud)

控制台打印的结果 在此输入图像描述

正确的情况是每次滑动仅打印一次

只是在ios14.2中有问题,14.1就可以了,你可以在Github上加载我的代码: https: //github.com/werbhelius/TabViewBug

Xcode 版本:12.1 (12A7403)

设备: iPhone 6s iOS 14.2

我认为您可以在 iOS 14.2 中的任何设备上重现此问题

我期待您的帮助来解决这个问题。谢谢

lor*_*sum 4

View由 SwiftUI 自行决定预加载。有时比其他人更多,具体取决于设备的可用资源。onAppear即使它出现在视图之外(预加载)也会被调用

import SwiftUI

struct PageView: View {
    
    @StateObject var vm = PageViewModel()
    
    var body: some View {
        VStack {
            
            DragViewBar().padding(.top, 14)
            
            TabView(selection: $vm.selectTabIndex) {
                
                TextView(index: "0").tag(0)
                TextView(index: "1").tag(1)
                TextView(index: "2").tag(2)
                TextView(index: "3").tag(3)
                TextView(index: "4").tag(4)
                TextView(index: "5").tag(5)
                
            }
            //This lets you perform an operation when the value has changed
            .onReceive(vm.$selectTabIndex, perform: { idx in
                print("PageView :: body :: onReceive" + idx.description)
            })
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            
        }

    }
}

struct TextView: View {
    
    let index: String
    
    var body: some View {
        VStack {
            Text(index)
        }
        //Views are pre-loaded at the discretion of SwiftUI
        .onAppear { print(index) }
        
        .onReceive(index.publisher, perform: { idx in
            print("TextView :: body :: onReceive" + idx.description)
        })
        
    }
}

struct DragViewBar: View {
    var body: some View {
        Rectangle()
            .frame(width:36.0,height:5.0).foregroundColor(Color.blue)
            .cornerRadius(100)
    }
}

class PageViewModel: ObservableObject {
    @Published var selectTabIndex = 0
}


struct PageView_Previews: PreviewProvider {
    static var previews: some View {
        PageView()
    }
} 
Run Code Online (Sandbox Code Playgroud)

  • 但我只是在14.2上重复调用onAppear时才发现这个问题,这对于14.1版本来说是正常的,我怀疑这是ios 14.2上TabView的一个bug (2认同)