You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SwiftUI导航栏标题在iPhone XR上部分隐藏(iPhone 7 Plus显示正常)

解决iPhone XR上导航栏标题被部分隐藏的问题

我来帮你排查这个在iPhone XR上导航栏标题被截断的问题~这类情况通常是SwiftUI在刘海屏设备上的安全区域布局计算冲突导致的,结合你的代码来看,主要是外层视图的安全区域设置干扰了NavigationView的正常布局,下面给你几个具体的解决方案:

可能的问题根源

  1. 外层的edgesIgnoringSafeArea(.all)会强制忽略所有设备的安全区域,而iPhone XR这类刘海屏设备的导航栏需要顶部安全区空间来展示标题,这个设置直接导致标题被顶到了屏幕边缘以外。
  2. statusBar(hidden: true)隐藏状态栏后,系统没有预留顶部状态栏的空间,但NavigationView仍然按照默认逻辑布局,进一步加剧了标题的遮挡问题。
  3. NavigationView被嵌套在多层VStack中,外层的背景和padding设置会传递到内部,打乱了导航栏的布局计算。

解决方案1:拆分安全区域设置,避免影响NavigationView

edgesIgnoringSafeArea只应用到LoginView和ResetView上,不给NavigationView添加该设置,让它自己处理刘海屏的安全区域:

var body: some View {
    LoadingView(isShowing: .constant(self.isShowLoadingView)) {
        VStack {
            if(self.showLoginView) {
                LoginView()
                    .edgesIgnoringSafeArea(.all) // 仅给登录视图设置忽略安全区
            } else if(self.showResetView) {
                ResetView()
                    .edgesIgnoringSafeArea(.all) // 重置视图同理
            } else {
                NavigationView {
                    VStack(alignment: .leading) {
                        Text(EMAIL).foregroundColor(Color.white)
                        TextField("", text: self.$emailid)
                            .foregroundColor(Color.black)
                            .padding(EdgeInsets(top: 0, leading: 0, bottom: 45, trailing: 0))
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                        Text(PHONE_NUMBER).foregroundColor(Color.white)
                        TextField("", text: self.$phoneno)
                            .foregroundColor(Color.black)
                            .padding(EdgeInsets(top: 0, leading: 0, bottom: 45, trailing: 0))
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                        Button(action: self.forgotPwdAction) {
                            HStack(alignment: .center) {
                                Spacer()
                                Text(OK_BTN).font(.headline).fontWeight(.bold).foregroundColor(Color.white).multilineTextAlignment(.center)
                                Spacer()
                            }
                        }.padding().background(Color.green)
                        Spacer()
                    }.padding(40)
                    .background(Color.black)
                    .navigationBarTitle("Forgot Password")
                    .navigationBarItems(leading: self.btnBack)
                }
            }
        }
        .background(Color.black)
        .statusBar(hidden: true)
    }
}

解决方案2:强制指定导航栏标题显示模式

给导航栏标题添加displayMode参数,明确指定显示样式,避免不同设备的自适应差异:

NavigationView {
    VStack(alignment: .leading) {
        // 原有内容不变
    }
    .padding(40)
    .background(Color.black)
    .navigationBarTitle("Forgot Password", displayMode: .inline) // 或者使用.large
    .navigationBarItems(leading: self.btnBack)
}

解决方案3:重构布局,让NavigationView作为根容器

把NavigationView作为最外层的容器之一,所有视图都在导航容器内切换,这样安全区域的管理会更统一:

var body: some View {
    LoadingView(isShowing: .constant(self.isShowLoadingView)) {
        NavigationView {
            ZStack {
                Color.black.edgesIgnoringSafeArea(.all)
                
                if self.showLoginView {
                    LoginView()
                } else if self.showResetView {
                    ResetView()
                } else {
                    VStack(alignment: .leading) {
                        Text(EMAIL).foregroundColor(Color.white)
                        TextField("", text: self.$emailid)
                            .foregroundColor(Color.black)
                            .padding(EdgeInsets(top: 0, leading: 0, bottom: 45, trailing: 0))
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                        Text(PHONE_NUMBER).foregroundColor(Color.white)
                        TextField("", text: self.$phoneno)
                            .foregroundColor(Color.black)
                            .padding(EdgeInsets(top: 0, leading: 0, bottom: 45, trailing: 0))
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                        Button(action: self.forgotPwdAction) {
                            HStack(alignment: .center) {
                                Spacer()
                                Text(OK_BTN).font(.headline).fontWeight(.bold).foregroundColor(Color.white).multilineTextAlignment(.center)
                                Spacer()
                            }
                        }.padding().background(Color.green)
                        Spacer()
                    }.padding(40)
                    .navigationBarTitle("Forgot Password")
                    .navigationBarItems(leading: self.btnBack)
                }
            }
            .statusBar(hidden: true)
        }
    }
}

内容的提问来源于stack exchange,提问作者cto platform

火山引擎 最新活动