首页 > 解决方案 > SwiftUI:在容器内均匀分布视图?

问题描述

假设我有ZStack一个不确定/灵活的宽度。这里面有四种观点ZStack。我将如何均匀地分配视图......就好像我正在展开一副卡片(每张卡片与下一张卡片重叠),如下所示:

扇子

.offset(x: ?)如果我知道容器的宽度,我可以实现这个效果:

ZStack {
    Text("One")
        .frame(width: 99, height: 150, alignment: .topLeading)
        .background(Color.blue)
        .offset(x: -99)
    Text("Two")
        .frame(width: 99, height: 150, alignment: .topLeading)
        .background(Color.red)
        .offset(x: -33)
    Text("Three")
        .frame(width: 99, height: 150, alignment: .topLeading)
        .background(Color.orange)
        .offset(x: 33)
    Text("Four")
        .frame(width: 99, height: 150, alignment: .topLeading)
        .background(Color.green)
        .offset(x: 99)
}

但是如果我不知道容器的宽度怎么办?或者如果它改变了怎么办?或者如果容器内的视图数量发生变化怎么办?

基本上,我只需要ZStack均匀地分布视图......无论宽度是多少。如何?

标签: swiftui

解决方案


既然你有那么多卡,你应该使用ForEach. 这将使添加/删除卡片更容易并节省一些代码。

但是如果我不知道容器的宽度怎么办?

这就是GeometryReader进来的地方!您可以使用它来获取容器的宽度。

我只需要在 ZStack 内均匀分布视图

从 中获得宽度后GeometryReader,您只需除以卡片数组中的元素数即可计算出每张卡片的宽度。

struct Card {
    var name: String
    var color: Color
}

struct ContentView: View {

    let cards = [
        Card(name: "One", color: .blue),
        Card(name: "Two", color: .red),
        Card(name: "Three", color: .orange),
        Card(name: "Four", color: .green)
    ]
    
    var body: some View {
        ZStack {
            GeometryReader { proxy in
                ForEach(cards.indices, id: \.self) { index in
                    let card = cards[index]
                    
                    Text(card.name)                                             /// add a bit of overlap
                        .frame(width: proxy.size.width / CGFloat(cards.count) + 10, height: 150, alignment: .topLeading)
                        .background(
                            card.color
                                .shadow(color: Color.black, radius: 5) /// make the overlap a bit more visible
                        )
                        .offset(x: proxy.size.width / CGFloat(cards.count) * CGFloat(index))
                }
                .frame(maxHeight: .infinity) /// center the cards vertically
            }
        }
    }
}

结果:

卡片水平排列均匀,有轻微重叠


推荐阅读