SwiftUI View - viewDidLoad ()? - PullRequest
       11

SwiftUI View - viewDidLoad ()?

6 голосов
/ 07 июня 2019

При попытке загрузить изображение после загрузки вида объект модели, управляющий видом (см. Ниже MovieDetail), имеет строку urlString. Поскольку элемент SwiftUI View не имеет методов жизненного цикла (и не управляет контроллером представления), каков наилучший способ справиться с этим?

Основная проблема, с которой я сталкиваюсь, заключается в том, каким образом я пытаюсь решить проблему (привязка объекта или использование переменной состояния), в моем представлении не отображается urlString до тех пор, пока не будет загружена ...

// 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)
            }
        }
    }
}

Заранее спасибо.

1 Ответ

11 голосов
/ 07 июня 2019

Надеюсь, это полезно. Я нашел пост в блоге , в котором говорится о том, как делать что-то в Appar для представления навигации.

Идея состоит в том, что вы запекаете свой сервис в BindableObject и подписываетесь на эти обновления в вашем представлении.

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 = []
                }
            }
        }
    }
}

Кредит: Маджид Джабраилов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...