SwiftUI 视图 - viewDidLoad()? [英] SwiftUI View - viewDidLoad()?

查看:21
本文介绍了SwiftUI 视图 - viewDidLoad()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在视图加载后尝试加载图像,驱动视图的模型对象(参见下面的 MovieDetail)有一个 urlString.因为 SwiftUI View 元素没有生命周期方法(并且没有驱动事物的视图控制器)什么是最好的处理方法?

Trying to load an image after the view loads, the model object driving the view (see MovieDetail below) has a urlString. Because a SwiftUI View element has no life cycle methods (and there's not a view controller driving things) what is the best way to handle this?

我遇到的主要问题是无论我尝试以哪种方式解决问题(绑定对象或使用状态变量),我的视图都没有 urlString 直到它之后加载...

The main issue I'm having is no matter which way I try to solve the problem (Binding an object or using a State variable), my View doesn't have the urlString until after it loads...

// movie object
struct Movie: Decodable, Identifiable {

    let id: String
    let title: String
    let year: String
    let type: String
    var posterUrl: String

    private enum CodingKeys: String, CodingKey {
        case id = "imdbID"
        case title = "Title"
        case year = "Year"
        case type = "Type"
        case posterUrl = "Poster"
    }
}

// root content list view that navigates to the detail view
struct ContentView : View {

    var movies: [Movie]

    var body: some View {
        NavigationView {
            List(movies) { movie in
                NavigationButton(destination: MovieDetail(movie: movie)) {
                    MovieRow(movie: movie)
                }
            }
            .navigationBarTitle(Text("Star Wars Movies"))
        }
    }
}

// detail view that needs to make the asynchronous call
struct MovieDetail : View {

    let movie: Movie
    @State var imageObject = BoundImageObject()

    var body: some View {
        HStack(alignment: .top) {
            VStack {
                Image(uiImage: imageObject.image)
                    .scaledToFit()

                Text(movie.title)
                    .font(.subheadline)
            }
        }
    }
}

提前致谢.

推荐答案

我希望这会有所帮助.我找到了一篇博文,其中谈到了如何做东西 onAppear 用于导航视图.

I hope this is helpful. I found a blogpost that talks about doing stuff onAppear for a navigation view.

想法是您将服务烘焙到 BindableObject 并在您的视图中订阅这些更新.

Idea would be that you bake your service into a BindableObject and subscribe to those updates in your view.

struct SearchView : View {
    @State private var query: String = "Swift"
    @EnvironmentObject var repoStore: ReposStore

    var body: some View {
        NavigationView {
            List {
                TextField($query, placeholder: Text("type something..."), onCommit: fetch)
                ForEach(repoStore.repos) { repo in
                    RepoRow(repo: repo)
                }
            }.navigationBarTitle(Text("Search"))
        }.onAppear(perform: fetch)
    }

    private func fetch() {
        repoStore.fetch(matching: query)
    }
}

import SwiftUI
import Combine

class ReposStore: BindableObject {
    var repos: [Repo] = [] {
        didSet {
            didChange.send(self)
        }
    }

    var didChange = PassthroughSubject<ReposStore, Never>()

    let service: GithubService
    init(service: GithubService) {
        self.service = service
    }

    func fetch(matching query: String) {
        service.search(matching: query) { [weak self] result in
            DispatchQueue.main.async {
                switch result {
                case .success(let repos): self?.repos = repos
                case .failure: self?.repos = []
                }
            }
        }
    }
}

感谢:Majid Jabrayilov

Credit to: Majid Jabrayilov

这篇关于SwiftUI 视图 - viewDidLoad()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆