下面的代码创建了一个简单的NavigationView
结构,其中包含两个子视图:LoggedOutView
带有一个按钮,该按钮通过一个简单的输入字段指向RegistrationView
。我使用GeometryReader
是因为如果不直接指定许多使用的UI元素的框架尺寸,它将无法正确布局(例如,LoggedOutView
中的底部元素应该始终保持在底部)。此外,视图应该在一个ScrollView
的弹性拖动效果,但似乎这对问题没有影响。
问题是,当导航到RegistrationView
并在模拟器(或设备)上使用软键盘时聚焦输入字段时,导航视图立即反弹回LoggedOutView
(或者更确切地说,ContentView
自动转到LoggedOutView
)。在模拟器中未激活软键盘时不会发生该问题,因此看起来是因为软键盘显示布局存在冲突,迫使导航视图返回。
我在Xcode中没有得到这个问题的错误日志,我不知道为什么会发生这个问题,但也许我的LoggedOutView
没有正确设置?对于SwiftUI 2,问题发生在iOS 14和15上。
ContentView
import SwiftUI
enum NavigationViewTarget: String {
case ContentView
case LoggedOutView
case RegistrationView
}
struct ContentView: View {
@State private var navigationViewTarget: NavigationViewTarget? = .ContentView
var body: some View {
GeometryReader {
geo in
NavigationView {
NavigationLink(destination: LoggedOutView(), tag: .LoggedOutView, selection: $navigationViewTarget) { EmptyView() }
.hidden()
.navigationBarHidden(true)
}
.frame(width: geo.size.width, height: geo.size.height)
.onAppear(perform: onAppear)
}
}
private func onAppear() {
navigationViewTarget = .LoggedOutView
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
LoggedOutView
import SwiftUI
struct LoggedOutView: View {
@State private var navigationViewTarget: NavigationViewTarget? = .LoggedOutView
var body: some View {
GeometryReader {
geo in
ScrollView(showsIndicators: false) {
VStack(alignment: .leading) {
Spacer().frame(maxWidth: .infinity, maxHeight: 28.0)
RoundedRectangle(cornerRadius: 10)
.scaledToFit()
.frame(width: abs(geo.size.width - 60), height: abs(geo.size.width - 60))
.padding(.leading, 30)
.padding(.trailing, 30)
.foregroundColor(.gray)
Spacer().frame(maxWidth: .infinity)
.layoutPriority(-1)
HStack {
NavigationLink(destination: RegistrationView(), tag: .RegistrationView, selection: $navigationViewTarget) { EmptyView() }.hidden()
Button(action: { navigationViewTarget = .RegistrationView }) {
Spacer()
Text("Register").padding(16)
Spacer()
}
.frame(height: 45)
.background(.red)
.foregroundColor(.white)
}
.frame(width: abs(geo.size.width - 60))
.padding(.leading, 30)
.padding(.trailing, 30)
Spacer().frame(maxWidth: .infinity, minHeight: 90)
.layoutPriority(-2)
VStack {
RoundedRectangle(cornerRadius: 10)
.frame(width: abs(geo.size.width - 60), height: 50)
.padding(.leading, 30)
.padding(.trailing, 30)
.foregroundColor(.gray)
}
.frame(width: geo.size.width)
.padding(.bottom, 16)
}
.frame(height: abs(geo.size.height - geo.safeAreaInsets.bottom))
.padding(30)
}
.frame(width: geo.size.width)
.navigationBarHidden(true)
.navigationBarTitleDisplayMode(.inline)
.navigationViewStyle(StackNavigationViewStyle())
}
}
}
struct LoggedOutView_Previews: PreviewProvider {
static var previews: some View {
NavigationView
{
LoggedOutView()
.navigationBarTitleDisplayMode(.inline)
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarHidden(true)
}
}
}
注册查看
import SwiftUI
struct RegistrationView: View {
@State var email = ""
var body: some View {
GeometryReader {
geo in
ScrollView(showsIndicators: false) {
VStack(alignment: .leading) {
Spacer().frame(maxWidth: .infinity, maxHeight: 10)
VStack(alignment: .leading, spacing: 16) {
VStack(alignment: .leading, spacing: 2) {
TextField("Email", text: $email)
}
}
}
.padding(30)
}
.frame(width: geo.size.width, height: geo.size.height)
.navigationBarTitleDisplayMode(.inline)
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarHidden(false)
}
.navigationBarTitle("Registration", displayMode: .inline)
}
}
struct RegistrationView_Previews: PreviewProvider {
static var previews: some View {
NavigationView
{
RegistrationView()
.navigationBarTitleDisplayMode(.inline)
.navigationViewStyle(StackNavigationViewStyle())
}
}
}
2条答案
按热度按时间f0brbegy1#
我发现了一个修复程序,使它的工作,但只有在iOS 15。从
ContentView
中完全删除Geo reader和one frame属性似乎可以解决整个问题。我仍然不知道为什么它不喜欢我用.frame(width: geo.size.width, height: geo.size.height)
显式地为NavigationView
设置宽度和高度。编辑:似乎每当使用geo阅读器并且框架高度设置在geo的某个地方时,这个问题就一定会发生在导航视图中。我最终删除了所有的几何阅读器,并依靠window.width和height代替。
i2byvkas2#
您需要将NavigationView从GeometryReader中拉出。
就在
这样不对