swiftui - 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
均匀地分布视图......无论宽度是多少。如何?
解决方案
既然你有那么多卡,你应该使用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
}
}
}
}
结果:
推荐阅读
- windows - 将 PowerShell foreach 循环转换为 /f 循环的批处理文件
- javascript - 如何在多个函数调用中保留相同的随机数?
- javascript - 函数节点 js 的数组别名
- lua - [{n,{}}] 在 lua 中做了什么?
- python - 禁用键盘但不断收到事件
- android - 当移动应用程序处于后台(iOS 和 Android)时,这个持续的通话中/进行中栏是什么?
- python - 有效的工作域给出“socket.gaierror: [Errno -2] Name or service not known”
- git - 更改 git 远程 url 以包含用户名而不丢失分支跟踪信息
- mailkit - winautomation V8 中的 MailKit 不接受阿拉伯字母
- c++ - Why does my display function terminate the program?