微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用SwiftUI模拟CSS flex-wrap行为

如何解决使用SwiftUI模拟CSS flex-wrap行为

我正在编写一个SwiftUI应用,并且想要一个容器视图,该视图将其子级“推送”到一行中,一旦该行填满,便开始将后续子级包装到后续行中,换句话说,就是一个模仿CSS flexBoxflex-wrap: wrap属性的行为。子级具有可变的动态宽度,但是高度相同(尽管我怀疑大多数非疯狂的解决方案对于可变高度都是健壮的)。孩子的数量也是动态的。

最上层,我的问题是:最简单的方法是什么?如果我需要深入UIKit或obj-c领域,就可以了,但是我更喜欢独立的解决方案(即不是pod Yoga)。

(注意:我是iOS开发人员的新手,但是熟悉React和所有〜newfangled 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。我得到了包装行为,但没有“弯曲”行为,至少从我的阅读看来,.adaptive声称是在锡罐上进行的。

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

解决方法

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

我认为您只需要设置alignment属性,即可获得与CSS flexbox的flex-wrap: wrap shown 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)
        }
    }
}
,

我对.adaptive的理解是不正确的-它的列总是 等距; maximum参数仅允许这些列扩展(以步进方式),以便它们共同填充父级的空间。我以为每列可以分别从最小宽度扩展到最大宽度。

一个朋友纠正了我,并给我链接了一个基于HStack的解决方案:SwiftUI HStack with Wrap

(我将这个问题搁置一旁,因为我发现上面链接的最佳Lazy*Grid文章,我认为在这点上可以同时解释为两种方式,因此是我的错误。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。