【问题标题】:Center View horizontally in SwiftUI在 SwiftUI 中水平居中视图
【发布时间】:2019-10-21 02:11:48
【问题描述】:

如何在HStack 中水平居中View (Image)?我想要一个按钮左对齐并且图像水平居中视图。

目前我有这个结构:

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()
    }

这是给我的:

但我想实现这个:

更新:

【问题讨论】:

  • HStack 之后Image 之后不需要另一个Spacer() 吗?
  • @ ielyamani - 不,由于他的填充,这在这种情况下不起作用。或者他也会在右侧添加一个填充......

标签: ios swift xcode user-interface swiftui


【解决方案1】:

您可以在ZStack 中嵌入两个HStack,并为水平间距放置相应的垫片。将所有内容嵌入到 VStackSpacer() 中,以将所有内容推到顶部。

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()
        }
    }
}

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

编辑:添加了 VStackSpacer() 以按照 OP 的要求将所有内容移到顶部。

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

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

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()
            }
        }
    }
}

用法

struct ContentView: View {
    let buttonSize: CGFloat = 30
    var body: some View {
        VStack {
            CustomNavBar(left: {
                Button(action: {
                    print("Tapped")
                }, label: {
                    Image(systemName: "star")
                        .resizable()
                        .frame(width: self.buttonSize, height: self.buttonSize, alignment: .leading)
                }).padding()
            }, center: {
                Image(systemName: "star")
                    .resizable()
                    .frame(width: 30, height: 30, alignment: .center)
            }, right: {
                HStack {
                    Text("Long text here")
                    Image(systemName: "star")
                        .resizable()
                        .frame(width: 30, height: 30, alignment: .center)
                        .padding(.trailing)
                }.foregroundColor(.red)
            })
            Spacer()
            Text("Normal Content")
            Spacer()
        }
    }
}

【讨论】:

  • 当上面的答案更简单且工作正常时,我为什么要使用你的答案。我不明白 ZStack 的东西以及它是什么等
  • @jsbeginnerNodeJS 你可以使用任何你想要的答案,但我的答案是更好的设计(imo)。如果您决定在另一个答案中向HBox 添加另一个视图(按钮、图像等),它会弄乱您的布局。根据我的回答,您可以在顶部添加任何内容,而不会弄乱按钮和图像的布局。由于按钮和图像不是彼此定位的.
  • 另外,ZStacks 在 Z 方向上排序孩子,就像在 x 方向上HStacks 在 x 方向上排序和在 y 方向上VStacks 上一样。它允许您将多个视图叠加在一起。来自维基百科关于 Z 顺序的文章,“类比是散落在桌子上的几张纸,每张纸都是一个窗口 [视图,在我们的例子中],桌子是你的计算机 [苹果设备,在我们的例子中]屏幕,以及具有最高 Z 值的顶层。”
  • 虽然我现在可以使用这些建议,但对于看起来很常见的用例来说,这些似乎并不明显。呃。
  • @ChrisPrince 您可以制作自己的 NavigationBar 式自定义视图,该视图采用独立的左对齐、右对齐和居中对齐 @ViewBuilder 闭包——这是 SwiftUI 模块化的一大优点。检查我的编辑(我决定这样做)。
【解决方案2】:

如何将按钮大小保存到属性并为图像添加负填充?并注意图片后面的额外间隔。

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()
        }
    }
}

结果:

【讨论】:

  • 使用 ZStack 而不是 VStack 以避免额外的填充内容(请参阅我的回答)。
  • 稍作修改即可工作,但为什么呢?我不知道为什么
  • @jsbeginnerNodeJS VStack 将按钮垂直放置在图像上方,负填充抵消了图像上的垂直位移。这是一种“hacky”的方法。我的答案使用 ZStack,它不需要偏移量,因为两个 HStack 在 Z 方向上相互重叠。
  • @RPatel99 您的回答无效。它没有居中。我问阿尔乔姆。
  • @jsbeginnerNodeJS 对不起,我的印象是这个答案是将图像作为另一个项目放在 VStack 中,所以忽略我之前的评论。填充偏移只是将按钮向左移动,但它仍然是一种“hacky”方式。为什么我的回答不起作用?当我测试它时它起作用了。我对其进行了编辑以包含我用来测试它的所有代码,所以如果你能告诉我为什么它不适合你,那就太好了。
【解决方案3】:

对我来说最简单的方法:

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)
}

【讨论】:

    【解决方案4】:

    您使用位置属性将视图居中尝试此代码

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 2012-09-04
      • 2014-12-18
      • 2017-08-24
      • 1970-01-01
      相关资源
      最近更新 更多