SwiftUI горизонтальное выравнивание от центра вправо - PullRequest
0 голосов
/ 16 марта 2020

Я пытаюсь выровнять динамическую коллекцию c (ie различного количества) видов справа от центрированного вида, не перемещая центральный вид из исходного, центрального положения.

Например, центральный вид - Text("12"), а виды справа - [Text("+3"), Text("+10"), Text("-1")], поэтому я хочу, чтобы виды справа от 12 отображались справа, а 12 - по центру по горизонтали на экране:

| 12 +3 +10 -1 |

Если я попытаюсь использовать HStack, 12 отойдет от центра. Можно ли использовать модификатор представления? ех. Text("12").alignToRight(...)

Это решение выравнивает коллекцию слева от правого края экрана, но это не одно и то же.

ZStack {
  Text("12")

  HStack(spacing: 4) {
    Spacer()
    Text("+3")
    Text("+10")
    Text("-1")
  }
}

Я бы предпочел не дублировать HStack слева и затем заставьте его исчезнуть, чтобы сбалансировать HStack справа (это нелепый способ создания макета, плюс пример, который я привожу здесь, прост, на самом деле я должен используйте ForEach над коллекцией динамических c), ie

HStack {

  Spacer()

  HStack(spacing: 4) {
    Spacer()
    Text("+3")
    Text("+10")
    Text("-1")
  }
  .opacity(0)

  Text("12")

  HStack(spacing: 4) {
    Spacer()
    Text("+3")
    Text("+10")
    Text("-1")
  }

  Spacer()

}

Использование чего-то вроде Text("12").overlay(myCollectionView.offset(x: 16) также является преимуществом, так как размер шрифта центрального текста будет меняться, и поэтому Я должен был бы также угадать и отрегулировать смещение вручную - я бы предпочел иметь отступ между двумя видами.

1 Ответ

2 голосов
/ 16 марта 2020

Здесь возможен подход, основанный на направляющих выравнивания. Протестировано с Xcode 11.3 / iOS 13.3.

demo

Определение пользовательского выравнивания

extension HorizontalAlignment {
   private enum HCenterAlignment: AlignmentID {
      static func defaultValue(in dimensions: ViewDimensions) -> CGFloat {
         return dimensions[HorizontalAlignment.center]
      }
   }
   static let hCenterred = HorizontalAlignment(HCenterAlignment.self)
}

выравнивание необходимого элемента внутреннего HStack с внешним VStack используя пользовательское руководство по выравниванию

struct TestRightCenterred: View {
    var body: some View {
        GeometryReader { gp in
            VStack(alignment: .hCenterred) {
                HStack(spacing: 4) {
                    Text("12").border(Color.red) // << just for test
                        .alignmentGuide(.hCenterred, computeValue: { $0.width / 2.0 })
                    Text("+3")
                    Text("+10")
                    Text("-1")
                }
            }
            .frame(maxWidth: gp.size.width, alignment: Alignment(horizontal: .hCenterred, vertical: .center))
        }
    }
}
...