如何在 SwiftUI 中创建居中对齐的导航栏,即使前导和尾随内容具有不同的宽度,标题也会居中

问题描述 投票:0回答:1

我正在尝试创建一个具有前导和尾随视图的导航栏,并且我的标题位于中心或左对齐。

一开始我尝试用一个简单的 HStack 来做到这一点:

Hstack{
   leading()
      .frame(alignment: .leading)
   Spacer()
   title()
   Spacer()
   trailing()
      .frame(alignment: .trailing)
}

这里的问题是它们的前导和尾随是: 1 - 可选,某些情况下只能显示提单,不能显示尾随 2 - 不同宽度的前导可以大于尾随,反之亦然

因此可能会导致标题未正确居中对齐的问题。

所以我尝试的是以下内容:

    @State var widthNavigation: CGFloat = 0.00
    @State var widthActions: CGFloat = 0.00
    @State var titleWidth: CGFloat = 0.00
    @State var totalWidth: CGFloat = 0.00

    public var body: some View {
      HStack(alignment: .center, spacing: 0) {
        navigationIcon()
          .background(GeometryReader { geoNav in
            Color.clear.onAppear { self.widthNavigation = geoNav.size.width }
          })

        title()
          .background(GeometryReader { geoTitle in
            Color
              .clear
              .onAppear {
                titleWidth = geoTitle.size.width
              }
            }
          )
          .offset(
            x: totalWidth/2 - titleWidth/2
          )

        actions()
          .background(GeometryReader { geoAct in
            Color.clear.onAppear { self.widthActions = geoAct.size.width }
          })
      }
      .background(
        GeometryReader { geometry in
          Color.clear.onAppear { self.totalWidth = geometry.size.width }
        }
      )
      .frame(maxWidth: .infinity)
      .padding(.horizontal, 8)
    }

基本上,此代码获取视图的宽度并尝试推断标题的偏移量。 (我尝试了许多不同的偏移逻辑,但仍然

这就是我需要实现的目标: Center aligned

这是我的总体结果: Wrong aligned

swift xcode swiftui
1个回答
0
投票

我建议将按钮和标题分成两层,以便标题独立于按钮。

A

ZStack
可用于组合两层:

ZStack {
    HStack {
        navigationIcon()
        Spacer()
        actions()
    }
    title()
}
.padding(.horizontal, 8)

如果存在标题过长且与图标组之一重叠的风险,那么您可以使用隐藏副本为按钮保留空间。由于您不知道哪个组最宽,因此您可以使用另一个

ZStack
来构建足迹:

private var footprintForIcons: some View {
    ZStack {
        navigationIcon()
        actions()
    }
    .disabled(true)
    .hidden()
}

然后使用如下:

ZStack {
    HStack {
        navigationIcon()
        Spacer()
        actions()
    }
    HStack {
        footprintForIcons
        title()
        footprintForIcons
    }
}
.padding(.horizontal, 8)
© www.soinside.com 2019 - 2024. All rights reserved.