Ios 如何根据具体设备动态更改SwiftUI中对象的绝对位置

Ios 如何根据具体设备动态更改SwiftUI中对象的绝对位置,ios,iphone,ipad,swiftui,Ios,Iphone,Ipad,Swiftui,我正在制作一个SwiftUI应用程序,并将其设计成“新形态”,但我的问题是,由于我使用绝对定位(由于我找不到任何其他可行的解决方案),该应用程序在iPhone 12 Pro上看起来不错,在其他手机/平板电脑上看起来很糟糕。我试着使用Spacer(),但我似乎不明白如何将顶部的“横幅”做成我想要的尺寸 我的代码 // //ContentView.swift 导入快捷键 分色{ 静态送风白色=颜色(红色:225/255,绿色:225/255,蓝色:235/255) 静态白色=颜色(红色:215/25

我正在制作一个SwiftUI应用程序,并将其设计成“新形态”,但我的问题是,由于我使用绝对定位(由于我找不到任何其他可行的解决方案),该应用程序在iPhone 12 Pro上看起来不错,在其他手机/平板电脑上看起来很糟糕。我试着使用Spacer(),但我似乎不明白如何将顶部的“横幅”做成我想要的尺寸

我的代码

//
//ContentView.swift
导入快捷键
分色{
静态送风白色=颜色(红色:225/255,绿色:225/255,蓝色:235/255)
静态白色=颜色(红色:215/255,绿色:215/255,蓝色:225/255)
静态let hellocolor=Color(红色:183/255,绿色:114/255,蓝色:126/255)
静态let StartPlayingColor=颜色(红色:114/255,绿色:138/255,蓝色:183/255)
}
延长线半径{
初始化(颜色:颜色…){
self.init(渐变:渐变(颜色:颜色),起始点:.topLeading,终点:.BottomTraining)
}
}
结构ContentView:View{
var body:一些观点{
ZStack{
灰白色
圆角转角(拐角半径:98)
.填充(颜色.白色)
.框架(宽:422,高:459)
.位置(x:183,y:125)
阴影(颜色:颜色。黑色。不透明度(0.2),半径:10,x:10,y:10)
阴影(颜色:彩色。白色。不透明度(0.7),半径:10,x:-5,y:-5)
文本(“Hello\nAmit”)
.foregroundColor(Color.hellocolor)
.font(字体自定义(“Rubik”,大小:72))
.multilitextalignment(.center)
.位置(x:183,y:180)
按钮(操作:{
打印(“点击按钮”)
}) {
文本(“开始播放”)
.foregroundColor(.StartPlayingColor)
.位置(x:193,y:382)
}
.buttonStyle(SimpleButtonStyle()).position(x:193,y:486)
}
}
}
结构SimpleButtonStyle:ButtonStyle{
func makeBody(配置:Self.configuration)->一些视图{
配置标签
.背景(
团体{
如果显示configuration.isPressed{
圆角反射角(角半径:98)。填充(颜色。白色)
.覆盖(
圆角转角(拐角半径:98)
.笔划(颜色.灰色,线宽:4)
.blur(半径:98)
.偏移量(x:2,y:2)
.mask(圆圈().fill(LinearGradient(Color.black,Color.clear)))
)
.覆盖(
圆角直角(拐角半径:98)。笔划(颜色。白色,线宽:8)
.模糊(半径:98)
.偏移量(x:-2,y:-2)
.mask(圆圈().fill(LinearGradient(Color.clear,Color.black)))
)
.框架(宽度:242,高度:91)
}
否则{
圆角反射角(角半径:98)。填充(颜色。白色)
阴影(颜色:颜色。黑色。不透明度(0.2),半径:10,x:10,y:10)
阴影(颜色:彩色。白色。不透明度(0.7),半径:10,x:-5,y:-5)
.框架(宽度:242,高度:91)
}
}
)
}
}
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView()
}
}
应用程序在多台设备上的图片


任何帮助都将不胜感激

这应该能让你在大部分方面达到目标——你可以做出调整,使它更接近你的理想状态

struct ContentView: View {
    var body: some View {
        ZStack {
            Color.offWhite.edgesIgnoringSafeArea(.all)
            
            VStack(spacing: 30) {
                VStack {
                    Text("Hello\nAmit")
                        .foregroundColor(Color.hellocolor)
                        .font(Font.custom("Rubik", size: 72))
                        .multilineTextAlignment(.center)
                }
                .frame(maxWidth: .infinity)
                .frame(height: 300)
                .background(
                    RoundedCorner(radius: 98, corners: [.bottomLeft, .bottomRight])
                        .fill(Color.superoffwhite)
                        .shadow(color: Color.black.opacity(0.2), radius: 10, x: 10, y: 10)
                        .shadow(color: Color.white.opacity(0.7), radius: 10, x: -5, y: -5)
                        .edgesIgnoringSafeArea(.top)

                )
                
                Button(action: {
                    print("Button tapped")
                }) {
                    Text("Start Playing")
                        .foregroundColor(.StartPlayingColor)
                }
                .buttonStyle(SimpleButtonStyle())
                .padding(.horizontal, 40)
                
                Spacer()
            }
            
        }
    }
}

struct RoundedCorner: Shape {

    var radius: CGFloat = .infinity
    var corners: UIRectCorner = .allCorners

    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        return Path(path.cgPath)
    }
}

struct SimpleButtonStyle: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .frame(maxWidth: .infinity)
            .frame(height: 91)
            .background(
                Group {
                    if configuration.isPressed {
                        RoundedRectangle(cornerRadius: 98)
                            .fill(Color.superoffwhite)
                            .overlay(
                                RoundedRectangle(cornerRadius: 98)
                                    .stroke(Color.gray, lineWidth: 4)
                                    .blur(radius: 98)
                                    .offset(x: 2, y: 2)
                                    .mask(Circle().fill(LinearGradient(Color.black, Color.clear)))
                            )
                            .overlay(
                                RoundedRectangle(cornerRadius: 98)                                 .stroke(Color.white, lineWidth: 8)
                                    .blur(radius: 98)
                                    .offset(x: -2, y: -2)
                                    .mask(Circle().fill(LinearGradient(Color.clear, Color.black)))
                            )
                    }
                    else {
                        RoundedRectangle(cornerRadius: 98)
                            .fill(Color.superoffwhite)
                            .shadow(color: Color.black.opacity(0.2), radius: 10, x: 10, y: 10)
                            .shadow(color: Color.white.opacity(0.7), radius: 10, x: -5, y: -5)
                    }
                }
            )
    }
}

我使用的工具:

  • 尽量避免硬编码顶部的安全区域(特别是考虑到不同设备上的安全区域大小不同)。相反,当您需要覆盖安全区域时,请利用
    .edgesIgnoringSafeArea

  • 当您需要准确描述某个尺寸(如高度)时,请使用
    frame
    。您还可以使用
    frame
    占用可用的宽度或高度,如下所示:
    .frame(maxWidth:.infinity)

  • 使用
    VStack
    垂直布局视图——不要依赖绝对定位

  • 我用了一个答案,从你的顶视图,只有底角是圆的

  • 使用
    填充
    间距
    分隔视图


  • 就像我说的,这会让你在大部分的过程中达到目标,尽管你可能需要做更多的调整。此外,请记住,在设计多种尺寸的设备时,有时您可能会被迫做出一些小的妥协,以使所有东西都适用于绝大多数尺寸


    您还可以查看
    GeometryReader
    ,了解您需要通过
    @Environment
    填充的大小和大小类的信息,以便根据不同的大小做出不同的决定。例如,我将俯视图的高度设置为
    300
    ,但您可以使用这些选项将该高度设置为可用屏幕大小。此外,您可以在上方视图的
    文本上使用
    填充
    ,使其尽可能高——这可能是我个人的选择。

    解决方案肯定是不使用绝对定位