UI 的布局方式完全取决于您,但此答案会创建一个水平滚动的 URL 列表,这些 URL 垂直堆叠为每个项目的一部分。
工作代码:
ScrollView(.horizontal) {
LazyHStack {
ForEach(items) { item in
VStack {
ForEach(item.urls) {
Text($0.absoluteString)
}
}
}
}
}
变化:
- 包裹
LazyHStack
在 中ScrollView
,因此可以滚动查看屏幕外的项目。
VStack
在 s 之间插入 a ForEach
,以确定每个 s 的布局item
。
id: \.self
从第二个中删除,因为您已经为 URLForEach
创建了自定义。id
在. id: \.id
_ id
_ForEach
结果:
另一种可能性是为每个元素设置一个唯一的 ID。基本上,如果多个 URL 相同(因此具有相同的 ID),则LazyHStack
存在 ID 并非都是唯一的问题。链接到此处的类似答案。这是不需要VStack
介于两者之间的替代修复:
Text($0.absoluteString)
.id(item.id.uuidString + ($0.id ?? ""))
编辑以支持可选 URL
数据的结构(这里唯一的区别URL
被替换为,URLItem
所以我们可以保存一个可选值):
struct Item: Identifiable {
let id = UUID()
let urls: [URLItem]
}
struct URLItem: Identifiable {
let id = UUID()
let url: URL?
init(_ url: URL?) {
self.url = url
}
}
新的示例数据:
let items: [Item] = [
Item(urls: [
URLItem(URL(string: "https://www.google.com")), URLItem(URL(string: "https://www.stackoverflow.com"))
]),
Item(urls: [
URLItem(URL(string: "https://www.stackoverflow.com")), URLItem(URL(string: ""))
])
]
这意味着我们现在可以拥有Identifiable
可选的 URL。代码现在应该如下所示:
ForEach(item.urls) {
if let url = $0.url {
Text(url.absoluteString)
.id($0.id)
} else {
Text("Bad URL")
.id($0.id)
}
}
您现在可以处理自己的案件 where $0.url
is nil
。