【问题标题】:SwiftUI - maxHeight: .infinity pushes VStack outside of safe area?SwiftUI - maxHeight:.infinity 将 VStack 推到安全区域之外?
【发布时间】:2020-12-15 18:54:56
【问题描述】:

我有一个身体:

var body: some View{
        VStack{
            Text(getGreeting())
                .font(.title)
                .fontWeight(.bold)
                .foregroundColor(.primary)
                .multilineTextAlignment(.center)
            Text("\("self.user.username")'s home")
                .font(.subheadline)
                .foregroundColor(.accentColor)
            Spacer()
        }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
}

我希望 VStack 填满手机屏幕的整个高度,这就是我添加框架的原因:

.frame(maxWidth: .infinity, maxHeight: .infinity)

它适用于所有带有凹槽的手机(安全区域位于两个状态栏下方并与安全区域发生反应:

但是,在没有缺口的手机(iPhone SE、iPhone 7/8 等)上这是正确的:

这是正常现象还是错误?我没有任何修改安全区域边界的修饰符。

更新:

如果我删除 .frame 修饰符(正如 pawello2222 正确所说的),我不需要同时使用垫片和 .frame,我仍然会得到这个错误的结果:

它仍然超出,应该是什么,安全区域?

所有代码:

主视图:

struct Main: View {

    @State var showLoginScreen = false

    var body: some View {
        if(showLoginScreen){
            LoginView()
        }else{
            TabView(showLoginScreen:      $showLoginScreen).hiddenNavigationBarStyle()
        }
    }
 }
struct TabView: View {
    
    @State var index = 0
    @Environment(\.colorScheme) var scheme
    @Binding var showLoginScreen: Bool
    
    var body: some View{
        VStack(spacing: 0){
            
            ZStack{
                Home(index: $index)
                    .opacity(self.index == 0 ? 1 : 0)
                    .animation(.spring())
                Control()
                    .opacity(self.index == 1 ? 1 : 0)
                    .animation(.spring())
                Account(showLoginScreen: $showLoginScreen)
                    .opacity(self.index == 2 ? 1 : 0)
                    .animation(.spring())
            }
            
            ZStack {
                Capsule()
                    .fill(Color.black)
                    .frame(height: 60)
                HStack{
                    Button(action: {
                        self.index = 0
                    }){
                        HStack(spacing: 6){
                            Image(systemName: "house")
                                .foregroundColor(.white)//index == 0 ? .white : .primary)
                            if self.index == 0{
                                Text("home")
                                    .foregroundColor(.white)
                            }
                        }
                        .padding(.vertical, 10)
                        .padding(.horizontal)
                        .background(self.index == 0 ? Color(#colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)) : Color.clear)
                        .clipShape(Capsule())
                    }
                    
                    Spacer(minLength: 0)
                    Button(action: {
                        self.index = 1
                    }){
                        HStack(spacing: 6){
                            Image(systemName: "text.justify")
                                .foregroundColor(.white)//index == 1 ? .white : .primary)
                            if self.index == 1{
                                Text("control")
                                    .foregroundColor(.white)
                            }
                        }
                        .padding(.vertical, 10)
                        .padding(.horizontal)
                        .background(self.index == 1 ? Color(#colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)) : Color.clear)
                        .clipShape(Capsule())
                    }
                    
                    Spacer(minLength: 0)
                    Button(action: {
                        self.index = 2
                    }){
                        HStack(spacing: 6){
                            Image(systemName: "person")
                                .foregroundColor(.white)//index == 2 ? .white : .primary)
                            if self.index == 2{
                                Text("account")
                                    .foregroundColor(.white)
                            }
                        }
                        .padding(.vertical, 10)
                        .padding(.horizontal)
                        .background(self.index == 2 ? Color(#colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)) : Color.clear)
                        .clipShape(Capsule())
                    }
                }
                
                .padding(.horizontal, 25)
                .padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.bottom == 0 ? 20 : UIApplication.shared.windows.first?.safeAreaInsets.bottom)
                .padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom == 0 ? 20 : UIApplication.shared.windows.first?.safeAreaInsets.bottom)
            }
            .padding()
        }
    }
}

它发生在所有视图(主页、控制、帐户)上,我只提供主页视图:

struct Home: View {

    @Binding var index: Int
    @EnvironmentObject var user: userData

    var body: some View{
            VStack{
                Text(getGreeting())
                    .font(.title)
                   .fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/)
                    .foregroundColor(.primary)
                    .multilineTextAlignment(.center)
                Text("\("self.user.username")'s home")
                    .font(.subheadline)
                    .foregroundColor(.accentColor)
                Spacer()
            }
       // .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

【问题讨论】:

  • 它不在提供的代码中,而是在父视图中。你会显示完整的屏幕代码吗?
  • @Asperi 请查看编辑

标签: ios swift swiftui


【解决方案1】:

我希望 VStack 填满手机屏幕的整个高度,这 这就是我添加框架的原因

您的VStack 中已经有一个Spacer,它会占用所有可用空间。

这意味着您的代码在没有 frame 修饰符的情况下可以正常运行:

var body: some View {
    VStack {
        Text(getGreeting())
            .font(.title)
            .fontWeight(.bold)
            .foregroundColor(.primary)
            .multilineTextAlignment(.center)
        Text("\("self.user.username")'s home")
            .font(.subheadline)
            .foregroundColor(.accentColor)
        Spacer()
    }
    // .frame(maxWidth: .infinity, maxHeight: .infinity) // remove
}

即使没有frame 修饰符,您的VStack 与屏幕的高度相同(因为Spacer)。

【讨论】:

  • 对不起,忘了提,我都试过了:没有框架修饰符/没有 Spacer(),请参阅更新的问题。
  • @Nathan 这是您的根视图吗?或者你有什么父视图?
  • 请查看编辑,我已经提供了所有相关的代码。
  • @Nathan 为什么需要这两行:.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom == 0 ? 20 : UIApplication.shared.windows.first?.safeAreaInsets.bottom)?尝试删除它们。
  • 我在 iPhone 设备上使用了滑动手势,因为我想要为滑动主页指示器提供额外的填充,删除它们对带有主页按钮的屏幕没有任何作用。
猜你喜欢
  • 2020-11-27
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 2019-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多