[英]How to pass data to a sub view from ContentView in SwiftUI
如果这没有意义,请原谅我,我是 Swift 的初学者。 我正在创建一个配方应用程序,它从 API 中提取数据并将其列在导航链接中。 当用户单击食谱时,我希望它移动到子视图并显示来自 API 的信息,例如食谱名称、图像、成分,并有一个带有网页链接的按钮。
我能够通过导航链接将数据拉入列表。 但是,现在我不知道如何使用我上面列出的所有信息设置配方详细信息子视图。
这就是我称之为 API 的地方:
class RecipeService {
func getRecipes(_ completion: @escaping (Result<[Recipe], Error>) -> ()) {
let url = URL(string: "http://www.recipepuppy.com/api")!
URLSession.shared.dataTask(with: url) { (data, _, error) in
if let error = error {
return completion(.failure(error))
}
guard let data = data else {
return completion(.failure(NSError(domain: "", code: -1, userInfo: nil)))
}
do {
let response = try JSONDecoder().decode(RecipesResponses.self, from: data)
completion(.success(response.results))
} catch {
completion(.failure(error))
}
}.resume()
}
}
这是我接受食谱回复的地方:
struct RecipesResponses: Codable {
let title: String
let version: Double
let href: String
let results: [Recipe]
}
struct Recipe: Codable {
let title, href, ingredients, thumbnail: String
var detail: URL {
URL(string: href)!
}
var thumb: URL {
URL(string: thumbnail)!
}
}
这是我的食谱 ViewModel:
class RecipeViewModel: ObservableObject {
@Published var recipes = [Recipe]()
@Published var isLoading = false
private let service = RecipeService()
init() {
loadData()
}
private func loadData() {
isLoading = true
service.getRecipes{ [weak self] result in
DispatchQueue.main.async {
self?.isLoading = false
switch result {
case .failure(let error):
print(error.localizedDescription)
case .success(let recipes):
self?.recipes = recipes
}
}
}
}
}
这是我的观点,我列出了 API 响应:
struct ListView: View {
@ObservedObject var viewModel = RecipeViewModel()
var body: some View {
NavigationView {
List(viewModel.recipes, id: \.href) { recipe in
NavigationLink (destination: RecipeDetailView()) {
HStack{
CachedImageView(recipe.thumb)
.mask(Circle())
.frame(width: 80)
VStack(alignment: .leading) {
Text(recipe.title)
.font(.largeTitle)
.foregroundColor(.black)
.padding()
}
}
.buttonStyle(PlainButtonStyle())
}
}
.navigationBarTitle(Text("All Recipes"))
}
}
}
struct ListView_Previews: PreviewProvider {
static var previews: some View {
ListView()
}
}
这是我想列出食谱详细信息并链接到网页的视图。 这是我努力将 API 数据提取到:
struct RecipeDetailView: View {
@ObservedObject var viewModel = RecipeViewModel()
var body: some View {
Text("Detail View")
}
}
struct RecipeDetailView_Previews: PreviewProvider {
static var previews: some View {
RecipeDetailView()
}
}
您可以更改RecipeDetailView
以接受Recipe
作为参数:
struct RecipeDetailView: View {
var recipe : Recipe
var body: some View {
Text(recipe.title)
Link("Webpage", destination: recipe.detail)
//etc
}
}
然后,在您的NavigationLink
中,将Recipe
传递给它:
NavigationLink(destination: RecipeDetailView(recipe: recipe)) {
我要警告您的一URL
Recipe
使用!
-- 你应该知道,如果你得到一个无效/格式错误的 URL,这种展开方式会使应用程序崩溃。
更新,向您展示预览的样子:
struct RecipeDetailView_Previews: PreviewProvider {
static var previews: some View {
RecipeDetailView(recipe: Recipe(title: "Recipe name", href: "https://google.com", ingredients: "Stuff", thumbnail: "https://linktoimage.com"))
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.