如何调整SwiftUI应用程序的UI以适应不同型号的iPhone?

huangapple go评论61阅读模式
英文:

How to adjust SwiftUI app UI for different iPhone models?

问题

Here is the translated content from your provided text:

"First-time SwiftUI developer here. My application UI works perfectly on the iPhone 14 and iPhone 14 Pro simulators, but when I run the iPhone SE simulator, it's completely off.

I understand that this is because of the differences in screen size and ratio between the keyboard and remaining display space on each individual device. Moreover, I have hard frame and border rules for my elements.

I have attached photos of what the screen must look like upon launching the app, as it is on the iPhone 14, vs. how broken it is on the iPhone SE.

Please assist me in getting this fixed; I've been working on it for 3 days now and can't seem to figure out the problem. I need the elements to remain the same and maintain a similar distance between one another, but:

  1. the logo, prompt, and textfield must begin at the top of the screen, barring a few units under the notch on the iPhone 14, and a few units under the time on the iPhone SE, and
  2. the continue button to lie right above the keyboard at all times.

Thank you so much in advance! Any help or pointers will be very much appreciated!

iPhone 14 UI:

如何调整SwiftUI应用程序的UI以适应不同型号的iPhone?

iPhone SE UI:

如何调整SwiftUI应用程序的UI以适应不同型号的iPhone?"

Note: The code part is not translated, as per your request.

英文:

First-time SwiftUI developer here. My application UI works perfectly on the iPhone 14 and iPhone 14 Pro simulators, but when I run the iPhone SE simulator, it's completely off.

I understand that this is because of the differences in screen size and ratio between the keyboard and remaining display space on each individual devices. Moreover I have hard frame and border rules for my elements.

I have attached photos of what the screen must look like upon launching the app, as it is on the iPhone 14, vs. how broken it is on the iPhone SE.

Please assist me in getting this fixed, I've been working on it for 3 days now and can't seem to figure out the problem. I need the elements to remain the same and maintain a similar distance between one another, but:

  1. the logo, prompt, and textfield must begin at the top of the screen, barring a few units under the notch on the iPhone 14, and a few units under the time on the iPhone SE, and
  2. the continue button to lie right above the keyboard at all times.

Thank you so much in advance! Any help or pointers will be very much appreciated!

iPhone 14 UI:

如何调整SwiftUI应用程序的UI以适应不同型号的iPhone?

iPhone SE UI:

如何调整SwiftUI应用程序的UI以适应不同型号的iPhone?

import SwiftUI

struct LoginEnterName: View {
    @State private var Fullname = ""
    @FocusState private var isTextFieldFocused: Bool
    @State private var isTextFieldFilled = false
    @State private var text: String = ""
    @State private var navigateToDOB = false
    
    var body: some View {
        LinearGradient(gradient: Gradient(colors: [Color("oasispitchblack"), Color("oasischocolate")]), startPoint: .topLeading, endPoint: .bottomTrailing)
            .preferredColorScheme(.dark)
            .edgesIgnoringSafeArea(.all)
            .overlay(
                
                VStack(spacing: 10){
               
                    Image("Appnx_Logo")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 130, height: 50)
                        .padding(.top, 15)
                    
//                    Text("~ O A S I S −").foregroundColor(Color.white)
//                        .font(.custom("Montserrat-Thin", size: 30))
//                        .bold()
//                        .padding(.top, 25)
                    
                    
                    Text("Let's get you set up, what’s your name?").foregroundColor(Color("oasisyellow"))
                        .padding(15)
                        .padding(.bottom, -15)
                    
                    
                    TextField("Your name", text: $Fullname)
                        .focused($isTextFieldFocused)
                        .foregroundColor(.white)
                        .padding()
                        .bold()
                        .multilineTextAlignment(.center)
                        .font(Font.system(size: 40))
                        .frame(width: 400, height: 50)
                        .background(Color.clear)
                        .cornerRadius(10)
                        .border(.clear)
                        .padding(.bottom, 25)
                        .onAppear {
                            isTextFieldFocused = true
                        }
                    Spacer()
                        .frame(height: 210)
                    
                    Button(action: {
                        navigateToDOB = true
                    }) {
                        Text("Continue")
                            .foregroundColor(.black)
                            .bold()
                            .padding()
                            .frame(minWidth: 360)
                            .background(
                                Group {
                                    if Fullname.count < 2 {
                                        Color.gray
                                    } else {
                                        Color.white
                                    }
                                }
                            )
                            .onSubmit {
                                performAction()
                            }
                            .background(Color.white)
                            .cornerRadius(20)
                            .padding(.horizontal)
                        
                    }
                    .disabled(Fullname.count < 2)
                    .onTapGesture {
                        navigateToDOB = true
                    }
                    .fullScreenCover(isPresented: $navigateToDOB) {
                        LoginEnterDOB()
                    }
                    .transition(.identity)
                }
                .frame(height: UIScreen.main.bounds.height / 1.8)
                .hAlign(.center)
                .vAlign(.top)
                .padding(20)
                .edgesIgnoringSafeArea(.all)
                
            )
    }
}

struct LoginEnterName_Previews: PreviewProvider {
    static var previews: some View {
        LoginEnterName()
    }
}

extension View{
    func hAlign(_ alignment: Alignment)->some View{
        self
            .frame(maxWidth: .infinity, alignment: alignment)
    }
    
    func vAlign(_ alignment: Alignment)->some View{
        self
            .frame(maxHeight: .infinity, alignment: alignment)
    }
    
    func performAction() {
        // Perform your action here
    }
    
    func capitalizeFirstLetterOfEachWord(_ text: String) -> String {
        let words = text.components(separatedBy: " ")
        let capitalizedWords = words.map { word -> String in
            guard let firstLetter = word.first else { return word }
            let restOfString = word.dropFirst()
            return String(firstLetter).capitalized + restOfString
        }
        return capitalizedWords.joined(separator: " ")
    }
}

答案1

得分: 1

将视图的整个内容包装在GeometryReader中,以便访问安全区域插图和屏幕的尺寸:

GeometryReader { geometry in
    VStack(spacing: 10) {
        // 这里放内容
    }
    .frame(width: geometry.size.width, height: geometry.size.height)
    .padding(.top, geometry.safeAreaInsets.top)
}

从LinearGradient中删除.edgesIgnoringSafeArea(.all)修饰符,以及从VStack中删除.edgesIgnoringSafeArea(.all)。我们将手动处理安全区域插图。

调整图像视图的填充以考虑安全区域插图:

.padding(.top, geometry.safeAreaInsets.top + 15)

通过使用GeometryReader和safeAreaInsets,确保内容在状态栏下正确定位,不受设备和其安全区域插图的影响。

英文:

Wrap the entire content of the view in a GeometryReader to get access to the safe area insets and the size of the screen:

GeometryReader { geometry in
    VStack(spacing: 10) {
        // Content here
    }
    .frame(width: geometry.size.width, height: geometry.size.height)
    .padding(.top, geometry.safeAreaInsets.top)
}

Remove the .edgesIgnoringSafeArea(.all) modifier from the LinearGradient and .edgesIgnoringSafeArea(.all) from the VStack. We'll handle the safe area insets manually.

Adjust the image view's padding to account for the safe area insets:

.padding(.top, geometry.safeAreaInsets.top + 15)

By using the GeometryReader and safeAreaInsets, you ensure that the content is positioned correctly below the status bar, regardless of the device and its safe area insets.

huangapple
  • 本文由 发表于 2023年5月22日 12:36:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76303066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定