将数据 JSON API 传递给 .sheet(isPresented) SwiftUI
Pass data JSON API to .sheet(isPresented) SwiftUI
如何将数据传递给.sheet(isPresented)
我从 JSON API 中获得了 10 个名字,但是当我单击这些名字时,.sheet(isPresented)
显示了一个名字。
在我所有的 10 个 .sheet(isPresented) 中只显示一个名字
struct Course: Hashable, Codable {
let name: String
}
class ViewModel: ObservableObject {
@Published var courses: [Course] = []
func fetch() {
guard let url = URL(string: "JSON URL") else {return}
let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
guard let data = data, error == nil else {return}
do {
let courses = try JSONDecoder().decode([Course].self, from: data)
DispatchQueue.main.async {
self?.courses = courses
}
}
catch {
print(error)
}
}
task.resume()
}
}
struct List: View {
@StateObject var viewModel = ViewModel()
@State var show = false
let columns: [GridItem] = [
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil)
]
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
LazyVGrid(columns: columns) {
ForEach(viewModel.courses, id: \.self) { course in
VStack {
Text(course.name)
.foregroundColor(.white)
.lineLimit(1)
.padding(.bottom)
}
.frame(width: 90, height: 90)
.background(Color.gray)
.onTapGesture {
self.show = true
}.sheet(isPresented: self.$show, onDismiss: {
self.show = false
}, content: {
Text(course.name)
})
}
}
}
.onAppear {
viewModel.fetch()
}
}
}
我从中获取姓名数据的 JSON API 看起来像这样
[
{
"id": 1,
"name": "Alex"
},
{
"id": 2,
"name": "Sam"
},
{
"id": 3,
"name": "Den"
}
]
抱歉,我不能在这里写 link
如果你不明白我问题的本质,请向我询问必要的细节。
如评论中所述,您需要切换到 sheet(item:)
形式并将其移出 ForEach
。您还希望您的模型符合 Identifiable
.
此外,即使您不想在此处主动使用 List
,您仍应将 您的 组件命名为其他名称以避免与同名 SwiftUI 组件。
struct Course: Hashable, Codable, Identifiable {
let id: Int
let name: String
}
class ViewModel: ObservableObject {
@Published var courses: [Course] = [
.init(id: 1, name: "Course 1"),
.init(id: 2, name: "Course 2"),
.init(id: 3, name: "Course 3"),
]
func fetch() {
//...
}
}
struct MyList: View {
@StateObject private var viewModel = ViewModel()
@State private var showItem: Course? = nil
let columns: [GridItem] = [
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil)
]
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
LazyVGrid(columns: columns) {
ForEach(viewModel.courses, id: \.self) { course in
VStack {
Text(course.name)
.foregroundColor(.white)
.lineLimit(1)
.padding(.bottom)
}
.frame(width: 90, height: 90)
.background(Color.gray)
.onTapGesture {
self.showItem = course
}
}
.sheet(item: $showItem) { course in
Text(course.name)
}
}
}
.onAppear {
viewModel.fetch()
}
}
}
如何将数据传递给.sheet(isPresented)
我从 JSON API 中获得了 10 个名字,但是当我单击这些名字时,.sheet(isPresented)
显示了一个名字。
在我所有的 10 个 .sheet(isPresented) 中只显示一个名字
struct Course: Hashable, Codable {
let name: String
}
class ViewModel: ObservableObject {
@Published var courses: [Course] = []
func fetch() {
guard let url = URL(string: "JSON URL") else {return}
let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
guard let data = data, error == nil else {return}
do {
let courses = try JSONDecoder().decode([Course].self, from: data)
DispatchQueue.main.async {
self?.courses = courses
}
}
catch {
print(error)
}
}
task.resume()
}
}
struct List: View {
@StateObject var viewModel = ViewModel()
@State var show = false
let columns: [GridItem] = [
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil)
]
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
LazyVGrid(columns: columns) {
ForEach(viewModel.courses, id: \.self) { course in
VStack {
Text(course.name)
.foregroundColor(.white)
.lineLimit(1)
.padding(.bottom)
}
.frame(width: 90, height: 90)
.background(Color.gray)
.onTapGesture {
self.show = true
}.sheet(isPresented: self.$show, onDismiss: {
self.show = false
}, content: {
Text(course.name)
})
}
}
}
.onAppear {
viewModel.fetch()
}
}
}
我从中获取姓名数据的 JSON API 看起来像这样
[
{
"id": 1,
"name": "Alex"
},
{
"id": 2,
"name": "Sam"
},
{
"id": 3,
"name": "Den"
}
]
抱歉,我不能在这里写 link 如果你不明白我问题的本质,请向我询问必要的细节。
如评论中所述,您需要切换到 sheet(item:)
形式并将其移出 ForEach
。您还希望您的模型符合 Identifiable
.
此外,即使您不想在此处主动使用 List
,您仍应将 您的 组件命名为其他名称以避免与同名 SwiftUI 组件。
struct Course: Hashable, Codable, Identifiable {
let id: Int
let name: String
}
class ViewModel: ObservableObject {
@Published var courses: [Course] = [
.init(id: 1, name: "Course 1"),
.init(id: 2, name: "Course 2"),
.init(id: 3, name: "Course 3"),
]
func fetch() {
//...
}
}
struct MyList: View {
@StateObject private var viewModel = ViewModel()
@State private var showItem: Course? = nil
let columns: [GridItem] = [
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil)
]
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
LazyVGrid(columns: columns) {
ForEach(viewModel.courses, id: \.self) { course in
VStack {
Text(course.name)
.foregroundColor(.white)
.lineLimit(1)
.padding(.bottom)
}
.frame(width: 90, height: 90)
.background(Color.gray)
.onTapGesture {
self.showItem = course
}
}
.sheet(item: $showItem) { course in
Text(course.name)
}
}
}
.onAppear {
viewModel.fetch()
}
}
}