SwiftUI - 如何在 HStack 中左、中、右对齐元素?

lll*_*lll 45 user-interface xcode ios swift swiftui

我正在创建一个 iOS 扫雷游戏,并希望在顶部有一个包含三条信息的栏:

  • 高分(奖杯符号旁边)[左]
  • 当前时间(计时器符号旁边)[CENTER]
  • 剩余炸弹数量(炸弹符号旁边)[右]

然而,正如您在底部的图片中看到的那样,元素并不是均匀对齐的 - 我猜垫片自动具有相同的尺寸。因此,由于屏幕左侧的文本比右侧的文本宽,因此中间的文本会向右偏移。

如何对齐这些项目,使中心时间/图像与左侧/右侧的其他对象完全位于中间?

我的代码如下所示:

struct GameView: View {
    @EnvironmentObject var game: Game
    @State var labelHeight = CGFloat.zero
    
    var body: some View {
        VStack(alignment: .center, spacing: 10) {
            Text("MINESWEEPER")
                .font(.system(size: 25, weight: .bold, design: .monospaced))
                .kerning(3)
                .foregroundColor(.red)
            
            HStack(alignment: .center, spacing: 5) {
                Image(systemName: "rosette")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .foregroundColor(.black)
                Text(game.highScoreString)
                    .font(.system(size: 15, weight: .bold, design: .monospaced))
                    .foregroundColor(.black)

                Spacer()
                
                Image(systemName: "timer")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .foregroundColor(.black)
                Text(game.timerString)
                    .font(.system(size: 15, weight: .bold, design: .monospaced))
                    .foregroundColor(.black)
                
                Spacer()
                
                Image("top_bomb")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                Text(String(game.bombsRemaining))
                    .font(.system(size: 15, weight: .bold, design: .monospaced))
                    .foregroundColor(.black)
                    .overlay(GeometryReader(content: { geometry in
                        Color.clear
                            .onAppear(perform: {self.labelHeight = geometry.frame(in: .local).size.height})
                    }))
            }
            .frame(width: UIScreen.main.bounds.width * 0.9, height: labelHeight, alignment: .center)

            BoardView()
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

游戏查看图片

Asp*_*eri 64

不要通过垫片对齐,而是将每个部分移动到单独的视图中,例如LeftHeaderCenterHeaderRightHeader和 使用框架对齐,这样可以按相等的尺寸精确分隔,例如

HStack {
  LeftHeader()
    .frame(maxWidth: .infinity, alignment: .leading)
  CenterHeader()
    .frame(maxWidth: .infinity, alignment: .center)
  RightHeader()
    .frame(maxWidth: .infinity, alignment: .trailing)
}
Run Code Online (Sandbox Code Playgroud)


sle*_*rfx 17

这可以使用 ZStack 、 HStack 和 Spacers 来实现。

     ZStack{
            
            HStack{
                Text("Left")
                Spacer()
            }
            
            HStack{
                Text("Center")
            }

            HStack{
                Spacer()
                Text("Right")
            }
            
        }
Run Code Online (Sandbox Code Playgroud)

即使删除左(或右)HStack,也不会影响其他组件或布局。

你可以通过添加像这样的填充让它看起来更好一点,

ZStack{
            
            HStack{
                Text("Left").padding([.leading])
                Spacer()
            }
            
            HStack{
                Text("Center")
            }

            HStack{
                Spacer()
                Text("Right").padding([.trailing])
            }
            
        }
Run Code Online (Sandbox Code Playgroud)