SwiftUI List 需要精确的位置来渲染结果,所以如果没有 [0] 等就不会渲染结果
Posted
技术标签:
【中文标题】SwiftUI List 需要精确的位置来渲染结果,所以如果没有 [0] 等就不会渲染结果【英文标题】:SwiftUI List requires exact position to render results, so won't render result without [0] etc 【发布时间】:2022-01-11 03:27:55 【问题描述】:在尝试从 SwiftUI 中的 REST API 端点解析一些数据时,我很难正确呈现到列表中。
在下面的示例中,我的 List 需要精确的数组位置来呈现结果,因此如果没有 [0]
等,它将不会显示任何内容...
我习惯于在 javascript 中使用 for 循环解决此类问题,并对其进行迭代以将每个数组位置分配给 [i]
,但在 SwiftUI 中我正在努力做同样的事情。
我认为这可能是我如何处理嵌套 JSON 对象的问题,但我们开始吧。我也相信这可能是一个简单的解决方案,我只是在这里空白。
我创建了一个测试端点,如果您需要在本地运行它可以从中获取(这已经在下面的示例中)。
澄清我要在这里做什么。我想遍历数组以引用(例如)Text(item.objects.title)
,而不必指定我要查找的数组中的哪个项目。可悲的是,使用 ForEach
不起作用,因为 List(viewModel.items, id: \.self) item in
本质上是在复制 ForEach
循环并且也不起作用。
型号
struct ObjectResponse: Hashable, Decodable
let objects: [Object]
struct Object: Hashable, Decodable
let slug: String
let title: String
let metadata: Metadata
struct Metadata: Hashable, Decodable
let published: String
let url: String
let snippet: String
let read: Bool
视图模型
class ContentViewModel: ObservableObject
@Published var items: [ObjectResponse] = []
func fetchData()
let api = "https://api.cosmicjs.com/v2/buckets/a5e294b0-55ee-11ec-942e-ef0a04148eb7/objects?pretty=true&query=%7B%22type%22%3A%22bookmarks%22%7D&read_key=fufvo5ceSy1W88afkchDIRjYrUIzErPw9YzcW2vQV1SxKqjNHo&limit=20&props=slug,title,content,metadata,"
guard let url = URL(string: api) else return
URLSession.shared.dataTask(with: url) (data, response, error) in
do
if let data = data
let result = try JSONDecoder().decode(ObjectResponse.self, from: data)
DispatchQueue.main.async
self.items = [result]
/* Prints out everything nicely
result.objects.forEach
print($0.title)
*/
else
print("No data")
catch (let error)
print(error)
.resume()
内容视图
struct ContentView: View
@ObservedObject var viewModel = ContentViewModel()
var body: some View
NavigationView
List(viewModel.items, id: \.self) item in
VStack(alignment: .leading)
Text(item.objects[0].title) // Requires me to provide array position
.navigationTitle("Bookmarks")
.onAppear(perform:
viewModel.fetchData()
)
JSON 响应示例
"objects": [
"slug": "the-navigation-bar-isnt-hidden-as-expected-in-swiftui",
"title": "The Navigation Bar Isn’t Hidden as Expected in SwiftUI",
"content": null,
"metadata":
"published": "28 Nov 2021 at 16:30",
"url": "https://betterprogramming.pub/swiftui-navigationbar-is-not-really-hidden-as-you-expect-785ff0425c86",
"snippet": "",
"read": true
,
"slug": "hey-facebook-i-made-a-metaverse-27-years-ago",
"title": "Hey, Facebook, I Made a Metaverse 27 Years Ago",
"content": null,
"metadata":
"published": "28 Nov 2021 at 21:39",
"url": "https://www.theatlantic.com/technology/archive/2021/10/facebook-metaverse-was-always-terrible/620546/",
"snippet": "Michel Baret / Gamma-Rapho / Getty In a booth at Ted’s Fish Fry, in Troy, New York, my friend Daniel Beck and I sketched out our plans for the metaverse. ",
"read": true
,
"slug": "when-big-tech-buys-small-tech-benedict-evans",
"title": "When big tech buys small tech — Benedict Evans",
"content": null,
"metadata":
"published": "28 Nov 2021 at 21:39",
"url": "https://www.ben-evans.com/benedictevans/2021/11/12/when-big-tech-buys-small-tech",
"snippet": "Acquisitions are a big part of the discussion around competition in tech today, and a big set of questions. It’s easy to say that we wouldn’t let Amazon buy Zappos or Google buy DoubleClick again, but everyone’s favourite puzzle is Instagram. ",
"read": false
],
"total": 171,
"limit": 3
【问题讨论】:
这里期望的行为是什么?循环遍历每个项目并将其包含在VStack
?你试过ForEach
吗?
嘿!没错,我想遍历数组以引用(例如)Text(item.objects.title)
,而不必指定我要查找的数组中的哪个项目。可悲的是,使用ForEach
不起作用,因为List(viewModel.items, id: \.self) item in
本质上是在复制ForEach
循环。所以我认为这与我的模型有关,但我不确定!
没有什么可以阻止您在 List 中使用 ForEach。我只是不清楚所需的输出是什么——不知何故,你将不得不处理输出中的嵌套数组。
哦,当然,我想我的挑战是我无法理解如何在ForEach
循环中进一步分解问题来解决这个问题。我猜你的意思是我可以使用ForEach
来迭代List
的数组以深入一层?
知道了!耶,终于。感谢 jnpdx 的推送。
【参考方案1】:
好的,解决了,感谢 jnpdx 的一点帮助。需要通过ForEach
循环进一步钻取该数组,如下所示:
List(viewModel.items, id: \.self) item in
ForEach(item.objects, id: \.self) bookmark in
VStack(alignment: .leading)
Text(bookmark.title)
【讨论】:
以上是关于SwiftUI List 需要精确的位置来渲染结果,所以如果没有 [0] 等就不会渲染结果的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI - 如何获取新创建的按钮的确切中心坐标/位置
如何在 SwiftUI 中将 Firebase 结果转换为 List