在SwiftUI中水平居中查看

jsb*_*eJS 2 user-interface xcode ios swift swiftui

如何在ViewImage)中水平居中HStack?我希望按钮保持左对齐,并且图像在视图中水平居中。

目前我有这个结构:

VStack {
        HStack {
            Button(action: {
                print("Tapped")
            }, label: {
                Image("left-arrow")
                    .resizable()
                    .frame(width: 30, height: 30, alignment: .leading)
            }).padding(.leading, 20)

            Spacer()

            Image("twitter-logo")
                .resizable()
                .frame(width: 30, height: 30, alignment: .center)

        }
        Spacer()
    }
Run Code Online (Sandbox Code Playgroud)

这给了我这个:

在此处输入图片说明

但我想实现这一目标:

在此处输入图片说明

更新:

在此处输入图片说明

Art*_*kov 26

将按钮大小保存到属性并为图像添加负填充是什么意思?并注意图像后的额外间隔。

struct ContentView: View {

    var buttonSize: Length = 30

    var body: some View {
        VStack {
            HStack {
                Button(action: {
                    print("Tapped")
                }, label: {
                    Image(systemName: "star")
                        .resizable()
                        .frame(width: buttonSize, height: buttonSize, alignment: .leading)
                })
                Spacer()
                Image(systemName: "star")
                    .resizable()
                    .frame(width: 30, height: 30, alignment: .center)
                    .padding(.leading, -buttonSize)
                Spacer()
            }
            Spacer()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明


DaW*_*guy 8

对我来说最简单的方法:

ZStack(){
    HStack{
        Image("star").resizable().foregroundColor(.white).frame(width: 50, height: 50)
        Spacer()
    }
        Image("star").resizable().font(.title).foregroundColor(.white).frame(width: 50, height: 50)
}
Run Code Online (Sandbox Code Playgroud)


小智 7

将标题(如导航栏)居中的正确方法:

HStack {

    Spacer()
        .overlay {
            HStack {
                Image(systemName: "star")
                Spacer()
            }
        }

    Text("Title")
             
    Spacer()
        .overlay {
            HStack {
                Spacer()
                Image(systemName: "star")
            }
        }
}
Run Code Online (Sandbox Code Playgroud)


RPa*_*l99 5

您可以将两个嵌入HStack到a中,ZStack并根据水平间距相应地放置垫片。将所有内容VStack与一起嵌入,将所有Spacer()内容推到顶部。

struct ContentView : View {
var buttonSize: Length = 30
var body: some View {
    VStack {
        ZStack {
            HStack {
                Button(action: {

                }, label: {
                    Image(systemName: "star")
                        .resizable()
                        .frame(width: CGFloat(30), height: CGFloat(30), alignment: .leading)
                }).padding(.leading, CGFloat(20))

                Spacer()
            }

            HStack {
                Image(systemName: "star")
                    .resizable()
                    .frame(width: CGFloat(30), height: CGFloat(30), alignment: .center)
            }
        }
        Spacer()
    }
}
Run Code Online (Sandbox Code Playgroud)

}

注意:在第二个HStack图像中,图像应自动居中对齐,但如果不对齐,则可以Spacer()在图像前后放置一个。

编辑:添加了VStackSpacer(),将所有内容移动到所需的OP顶部。

编辑2:删除图像上的填充,因为它导致图像从中心稍微偏移。由于它本身HStack并居中对齐,因此不需要填充。

编辑3:感谢@Chris Prince的评论,我决定制作一个简单的NavigationBar风格的自定义视图,您可以提供左,中和右参数来创建OP所需的效果(每组视图对齐)彼此独立):

struct ContentView : View {
var buttonSize: Length = 30
var body: some View {
    VStack {
        ZStack {
            HStack {
                Button(action: {

                }, label: {
                    Image(systemName: "star")
                        .resizable()
                        .frame(width: CGFloat(30), height: CGFloat(30), alignment: .leading)
                }).padding(.leading, CGFloat(20))

                Spacer()
            }

            HStack {
                Image(systemName: "star")
                    .resizable()
                    .frame(width: CGFloat(30), height: CGFloat(30), alignment: .center)
            }
        }
        Spacer()
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

struct CustomNavBar<Left, Center, Right>: View where Left: View, Center: View, Right: View {
    let left: () -> Left
    let center: () -> Center
    let right: () -> Right
    init(@ViewBuilder left: @escaping () -> Left, @ViewBuilder center: @escaping () -> Center, @ViewBuilder right: @escaping () -> Right) {
        self.left = left
        self.center = center
        self.right = right
    }
    var body: some View {
        ZStack {
            HStack {
                left()
                Spacer()
            }
            center()
            HStack {
                Spacer()
                right()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

模拟器上显示的示例代码


kis*_*eji 5

您使用 position 属性居中视图试试这个代码

Group{ // container View
   Image("twitter-logo")
            .resizable()
            .frame(width: 30, height: 30, alignment: .center)
}.position(x: UIScreen.main.bounds.width/2)
Run Code Online (Sandbox Code Playgroud)

  • 除非您的应用程序在 iPad 上与其他应用程序并排使用,否则有效。GeometryReader 更可靠。 (2认同)