简体   繁体   English

当键盘出现在 SwiftUI 中时 OnAppear 意外调用

[英]OnAppear calls unexpectedly when Keyboard Appears in SwiftUI

I am experiencing very odd behavior in SwiftUI 2.0 and iOS14.我在 SwiftUI 2.0 和 iOS14 中遇到了非常奇怪的行为。

When the keyboard appears on the screen, the OnAppear method of other tab's view called automatically.当键盘出现在屏幕上时,自动调用其他选项卡视图的 OnAppear 方法。

However, this works fine Xcode 11.7但是,这很好用 Xcode 11.7

Here is the issue in action.这是行动中的问题。 TabView 中的 TextField

Here is the code which produces the above error.这是产生上述错误的代码。

struct ContentView: View {
    var body: some View {
        TabView {
            DemoView(screenName: "Home")
                .tabItem {
                    Image.init(systemName: "star.fill")
                    Text("Home")
                }
            DemoView(screenName: "Result")
                .tabItem {
                    Image.init(systemName: "star.fill")
                    Text("Result")
                }
            DemoView(screenName: "More")
                .tabItem {
                    Image.init(systemName: "star.fill")
                    Text("More")
                }
        }
    }
}

struct DemoView:View {
    
    @State var text:String = ""
    var screenName:String
    var body: some View {
        VStack{
            Text(screenName)
                .font(.title)
            
            TextField("Buggy Keyboard Issue", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                
            Text("Issue : When keyboard appears, onAppear of other 2 tabs call automatically.")
                .font(.footnote)
        }
        .padding()
        .onAppear(perform: {
            debugPrint("OnAppear of : \(screenName)")
        })
    }
}

This seems to be a bug of SwiftUI 2.0 but not sure.这似乎是 SwiftUI 2.0 的一个错误,但不确定。 Any help will be appreciated.任何帮助将不胜感激。

Thanks谢谢

Having the same issue myself, I think this is a bug or something like that, however I came up with a solution maybe a workaround until apple will fix it.我自己也有同样的问题,我认为这是一个错误或类似的问题,但是我想出了一个解决方案,也许是一种解决方法,直到苹果修复它。

The thing that I did is basically I used a LazyVStack , and this seems to be working perfectly.我所做的事情基本上是我使用了LazyVStack ,这似乎工作得很好。

LazyVStack {
    VStack{
        Text(screenName)
            .font(.title)
        
        TextField("Buggy Keyboard Issue", text: $text)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            
        Text("Issue : When keyboard appears, onAppear of other 2 tabs call automatically.")
            .font(.footnote)
    }
    .padding()
    .onAppear(perform: {
        debugPrint("OnAppear of : \(screenName)")
})
}

Now the OnAppear method of other tab's view it is not called automatically when the keyboard appear.现在其他选项卡视图的OnAppear方法不会在键盘出现时自动调用。

解决方案

To avoid reloading your view try with on the TabView为避免重新加载您的视图,请在 TabView 上尝试

.ignoresSafeArea(.keyboard, edges: .bottom)

It only works on iOS 14它仅适用于 iOS 14

Just implemented the following workaround:刚刚实施了以下解决方法:

struct ContentView: View {
    var body: some View {
        TabView(selection: $selectedTab) {
            TabContentView(tag: 0, selectedTag: selectedTab) {
                Text("Some tab content")
            }
            .tabItem {
                Text("First tab")
            }
            TabContentView(tag: 0, selectedTag: selectedTab) {
                Text("Another tab content")
            }
            .tabItem {
                Text("Second tab")
            }
        }
    }
    
    @State private var selectedTab: Int = 0
}

private struct TabContentView<Content: View, Tag: Hashable>: View {
    init(tag: Tag, selectedTag: Tag, @ViewBuilder content: @escaping () -> Content) {
        self.tag = tag
        self.selectedTag = selectedTag
        self.content = content
    }

    var body: some View {
        Group {
            if tag == selectedTag {
                content()
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            } else {
                Color.clear
            }
        }
        .tag(tag)
    }

    private let tag: Tag
    private let selectedTag: Tag
    private let content: () -> Content
}

Not sure if it's stable enough but keyboard appearance doesn't trigger onAppear on tabs content anymore.不确定它是否足够稳定,但键盘外观不再在选项卡内容上触发onAppear

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM