SwiftUI HStack с элементами неравномерного размера - PullRequest
0 голосов
/ 11 октября 2019

Желаемый вывод

Ищите способ разбить HStack на неравные элементы, один занимает более половины экрана, а два других - 1/4 экрана (см. вложение).

Код:


   struct MyCategoryRow: View {

    var body: some View {
      VStack(alignment: .leading, spacing: 0) {
         HStack(spacing: 0) {
            ForEach(0...2, id: \.self) { block in

                   ColoredBlock()

            }.frame(minWidth: 0, maxWidth: .infinity, alignment: Alignment.topLeading)

      }
    }
  }

Таким образом, приведенный выше код приводит к HStack с 3 цветными блоками одинаковой ширины. Я попытался применить ширину, используя UIScreen.main.bounds.width, но этот подход не адаптируется к изменению ориентации. Я также пытался использовать GeometryReader следующим образом:

 GeometryReader {  g in
       ColoredBlock().frame(width: block == 0 ? g.size.width * 2 : g.size.width / 2) 
 }

Но это тоже не сработало, похоже, тот факт, что каждый ColoredBlock будет занимать 1/3 HStack, решается заранее.

Обновление с помощью layoutPriority:

struct MyCategoryRow: View {
    var body: some View {
      VStack(alignment: .leading, spacing: 0) {
         HStack(spacing: 0) {
            ForEach(0...2, id: \.self) { block in        
                   ColoredBlock(background: (block == 0) ? Constants.pastel1 : Constants.pastel2).layoutPriority(block == 0 ? 1.0 : 0.5)             
            }.frame(minWidth: 0, maxWidth: .infinity, alignment: Alignment.topLeading)         
      }
    }
  }


struct ColoredBlock: View {
    let background: Color

var body: some View {
    GeometryReader { geometry in
      VStack(spacing: 0){
         HStack {
           Text("Some text").padding(.horizontal, 15).padding(.top, 15)
         }.frame(alignment: .leading)
         VStack(alignment: .leading){
           Text("Some more text").font(.subheadline).fontWeight(.light)
         }.padding(.vertical, 10).padding(.horizontal, 15)
     }.background(self.background)
                .cornerRadius(15)
   }
  }
}

Результат:

Ответы [ 2 ]

0 голосов
/ 22 октября 2019

В конечном итоге я использовал GeometryReader в MyCategoryRow вместо ColoredBlock и передачу ширины в ColoredBlock

HStack {
    ForEach(0...2, id: \.self) { block in
        ColoredBlock(background: (block == 0) ? Constants.pastel1 : Constants.pastel2, width: block == 0 ? geometry.size.width / 2 : geometry.size.width / 4, height: 150.0)
     }
}

Это работает, хотя теперь мне приходится указывать высоту, которую я предпочел бы нежёстко. Если у кого-то есть лучшее решение, пожалуйста, дайте мне знать!

0 голосов
/ 11 октября 2019

Я думаю, что вам нужно .layoutPriority. Установите значение 1,0 для первого блока и 0,5 для второго и третьего блоков.

...