如何解决SwiftUI中出现键盘时,OnAppear意外调用
我在SwiftUI 2.0和iOS14中遇到了非常奇怪的行为。
当键盘出现在屏幕上时,其他选项卡视图的OnAppear方法将自动调用。
但是,这在Xcode 11.7上正常工作
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)")
})
}
}
这似乎是SwiftUI 2.0的错误,但不确定。 任何帮助将不胜感激。
谢谢
解决方法
为避免重新加载视图,请尝试在TabView上使用
.ignoresSafeArea(.keyboard,edges: .bottom)
仅适用于iOS 14
,我自己也遇到了同样的问题,我认为这是一个错误或类似的问题,但是我想出了一个解决方案,直到苹果将其修复。
我所做的基本上是使用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)")
})
}
现在其他选项卡视图的OnAppear
方法在出现键盘时不会自动调用。
刚刚实施了以下解决方法:
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
}
不确定它是否足够稳定,但键盘外观不再触发标签内容上的 onAppear
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。