【问题标题】:How to make the row fill the screen width with some padding using SwiftUI?如何使用 SwiftUI 使行用一些填充填充屏幕宽度?
【发布时间】:2019-10-03 20:55:10
【问题描述】:

我正在尝试创建一个包含向下增长的卡片或行的列表。它被添加到可以有多个列表的水平滚动视图中。

如何让卡片填满宽度 - 屏幕的一些填充?

当前代码是

struct RowView: View {
    var body: some View {
        Rectangle()
        .foregroundColor(.blue)
        .frame(width: 80, height: 80, alignment: .center)  // shows a square, but how to set size depending on screen?
        //.frame(minWidth: 100, maxWidth: .infinity, minHeight: 100, maxHeight: .infinity, alignment: .topLeading)  // nothing shows up
    }
}

struct ListView: View {
    var body: some View {
        ScrollView(.vertical) {
            VStack(spacing: 16) {
                RowView()
                RowView()
                RowView()
            }
            .padding()
        }
    }
}

struct ContentView: View {

    var body: some View {
        ScrollView(.horizontal) {
            HStack {
                ListView()
                ListView()
                ListView()
            }
        }
    }
}

我尝试使用GeometryReader,但它不起作用。

【问题讨论】:

    标签: swift swiftui ios13


    【解决方案1】:

    我尝试使用GeometryReader,但它不起作用。

    重要的是您在哪个View 组件中尝试了GeometryReader

    • 如果你在一个典型的View 中,它跨越了屏幕的大小,你会得到屏幕本身的widthheight

    • 如果你在ScrollView 环境中,你会得到

      • height 容器的.horizontal 对齐
      • .vertical对齐的情况下,容器的width

    我实际上无法通过.horizontal.vertical 对齐的滚动视图来想象您要实现的目标。但是您所说的 Card 类视图要一直跨越到屏幕宽度,您可以使用以下代码来实现它:(请参阅内联 cmets 以获得更好的理解)

    struct RowView: View {
        var body: some View {
            Rectangle()
                .foregroundColor(.blue)
                .frame(height: 150)
                .cornerRadius(10)
        }
    }
    
    struct ListView: View {
        var body: some View {
            // you won't get the width of the container if you embed this view inside a horizontal scroll view which is the case for you
            // so you have to impose the explicit width from the parent view
            ScrollView(.vertical) {
                VStack(spacing: 16) {
                    RowView()
                    RowView()
                    RowView()
                }
                .padding()
            }
        }
    }
    
    struct ContentView: View {
        var body: some View {
            GeometryReader { geometry in
                ScrollView(.horizontal) {
                    HStack {
                        // you have to be explicit about the width of each content of the scroll view as it can't determine width of each content by itself
                        ListView().frame(width: geometry.size.width)
                        ListView().frame(width: geometry.size.width)
                        ListView().frame(width: geometry.size.width)
                    }
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      要填充屏幕的宽度,您可以在 ContentView 中添加一个 GeometryReader 并使用它来设置 HStack 的宽度。在那里设置填充。

      (填充和框架的顺序很重要,GeometryReader 的放置以获取屏幕宽度也很重要。)

      至于高度,可以直接设置为矩形。这里有几个具有相似效果的选项。由于您说列表将向下增长并且矩形位于 ScrollView 中,因此设置固定高度是有意义的。

      struct RowView: View {
          var body: some View {
              Rectangle()
                  .foregroundColor(.blue)
                  .frame(height: 100)
                  //.frame(idealHeight: 100)
                  //.frame(minHeight: 100)
          }
      }
      
      struct ListView: View {
          var body: some View {
              ScrollView(.vertical) {
                  VStack(spacing: 16) {
                      RowView()
                      RowView()
                      RowView()
                  }
                  .padding()
              }
          }
      }
      
      struct ContentView: View {
          var body: some View {
              GeometryReader { geometry in
                  ScrollView(.horizontal) {
                      HStack {
                          ListView()
                          ListView()
                          ListView()
                      }
                      .padding()
                      .frame(width: geometry.size.width)
                  }
              }
          }
      }
      

      附:如果我正确理解您想要水平填充屏幕并且只会向下增长列表,那么您可能不需要 ContentView 中的水平 ScrollView。但是,如果这不是您想要做的,请澄清,因为此解决方案可能无法达到您想要的效果。

      【讨论】: