【问题标题】:emulating CSS flex-wrap behavior with SwiftUI使用 SwiftUI 模拟 CSS flex-wrap 行为
【发布时间】:2020-09-14 17:01:41
【问题描述】:

我正在编写一个 SwiftUI 应用程序,并且想要一个容器视图,它可以将其子项“推入”一行,并且一旦该行填满,就开始将后续子项包装到下一行——换句话说,一个模拟容器视图CSS flexbox 的 flex-wrap: wrap 属性的行为。孩子们具有可变的动态宽度,但高度相同(尽管我怀疑大多数非疯狂的解决方案对可变高度具有鲁棒性)。孩子的数量也是动态的。

toplevel,我的问题是:最简单的方法是什么?如果我需要使用 UIKit 或 obj-c 领域,就这样吧,但我更喜欢独立的解决方案(即,不是 pod Yoga)。

(注意:我是 iOS 开发新手,但熟悉 React 和所有新奇的 CSS 布局。)

到目前为止,我最好的领先优势是 iOS 14 附带的 LazyVGrid 视图。特别是,在我看来,一个没有最大值(默认为无穷大)的单个自适应 GridItem 应该可以解决问题……但确实如此不是,或者至少我还没弄清楚怎么做。 (我找到的*Grid 的最佳参考斜线唯一详细参考是:https://swiftui-lab.com/impossible-grids/

我最初尝试过这个:

let columns = [
  GridItem(.adaptive(minimum: 42), alignment: .leading)
]

同时

LazyVGrid(columns: columns, spacing: 10) {
  Text("Hello, world!")
    .fixedSize(horizontal: true, vertical: false)
    .border(Color.gray)
  Text("lol")
    .fixedSize(horizontal: true, vertical: false)
    .border(Color.gray)
  Text("bananananananananana")
    .fixedSize(horizontal: true, vertical: false)
    .border(Color.gray)
}

but that didn't work。设置显式较大的最大值(50000)也无济于事。我的理解是LazyVGrid 应该允许它的孩子扩展他们的网格单元,但这显然不是这里发生的事情。

我想确保这不是 Text 害羞和温顺并拒绝表达其尺寸偏好,所以我尝试使用框架更明确:

LazyVGrid(columns: columns, spacing: 10) {
  Text("sup")
    .border(Color.gray)
  Text("sup")
    .border(Color.gray)
  Text("sup")
    .frame(minWidth: 100, maxWidth: 100)
    .border(Color.gray)
  Text("sup")
    .border(Color.gray)
  Text("sup")
    .border(Color.gray)
  Text("sup")
    .border(Color.gray)
  Text("sup")
    .border(Color.gray)
  Text("sup")
    .border(Color.gray)
  Text("sup")
    .border(Color.gray)
  Text("sup")
    .border(Color.gray)
}

but this also doesn't work。我得到了包装行为,但不是“flex”行为,至少根据我的阅读,这是.adaptive 声称在锡上做的事情。

所以我的第二个问题是:我对自适应LazyVGrid 对其子项执行大小建议并协商其“自适应列”的大小的方式有什么误解?有没有办法用网格做我想做的事情,如果没有,为什么不(还有什么更好的计划)?

【问题讨论】:

    标签: ios swift swiftui


    【解决方案1】:

    编辑:意识到我专注于包装而不是您问题的弹性部分,并且不认为这是您所追求的。

    我觉得你只需要设置alignment属性就可以得到和CSS flexbox的flex-wrap: wrapshown at CSS tricks.一样的效果。

    这似乎对我有用,您的代码的唯一更改是在 LazyVGrid 初始化程序中设置 alignment: .leadingResult with alignment: .leading

    struct ContentView: View {
        
        let columns = [
          GridItem(.adaptive(minimum: 42), alignment: .leading)
        ]
        
        var body: some View {
            LazyVGrid(columns: columns, alignment: .leading, spacing: 10) {
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
              Text("sup")
                .border(Color.gray)
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      我对@9​​87654322@ 的理解不正确——它的列总是均匀分布; maximum 参数只允许这些列扩展(同步),以便它们共同填充父级的空间。我认为每一列都可以单独从最小宽度扩展到最大宽度。

      一位朋友纠正了我并将我链接到基于HStack 的解决方案:SwiftUI HStack with Wrap

      (我之所以留下这个问题,是因为我找到了最好的Lazy*Grid 文章,上面链接,我认为在这一点上可以双向解释,因此我的错误。)

      【讨论】:

        猜你喜欢
        • 2023-04-04
        • 2014-01-10
        • 2017-02-22
        • 2021-05-29
        • 1970-01-01
        • 2019-04-05
        • 1970-01-01
        • 2019-11-21
        相关资源
        最近更新 更多