SwiftUI View - viewDidLoad()?

前端 未结 3 705
忘了有多久
忘了有多久 2021-01-30 10:35

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

相关标签:
3条回答
  • 2021-01-30 11:05

    We can achieve this using view modifier.

    1. Create ViewModifier:
    struct ViewDidLoadModifier: ViewModifier {
    
        @State private var didLoad = false
        private let action: (() -> Void)?
    
        init(perform action: (() -> Void)? = nil) {
            self.action = action
        }
    
        func body(content: Content) -> some View {
            content.onAppear {
                if didLoad == false {
                    didLoad = true
                    action?()
                }
            }
        }
    
    }
    
    1. Create View extension:
    extension View {
    
        func onLoad(perform action: (() -> Void)? = nil) -> some View {
            modifier(ViewDidLoadModifier(perform: action))
        }
    
    }
    
    1. Use like this:
    struct SomeView: View {
        var body: some View {
            VStack {
                Text("HELLO!")
            }.onLoad {
                print("onLoad")
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-30 11:14

    Fully updated for Xcode 11.2, Swift 5.0

    I think the viewDidLoad() just equal to implement in the body closure.
    SwiftUI gives us equivalents to UIKit’s viewDidAppear() and viewDidDisappear() in the form of onAppear() and onDisappear(). You can attach any code to these two events that you want, and SwiftUI will execute them when they occur.

    As an example, this creates two views that use onAppear() and onDisappear() to print messages, with a navigation link to move between the two:

    struct ContentView: View {
        var body: some View {
            NavigationView {
                VStack {
                    NavigationLink(destination: DetailView()) {
                        Text("Hello World")
                    }
                }
            }.onAppear {
                print("ContentView appeared!")
            }.onDisappear {
                print("ContentView disappeared!")
            }
        }
    }
    

    ref: https://www.hackingwithswift.com/quick-start/swiftui/how-to-respond-to-view-lifecycle-events-onappear-and-ondisappear

    0 讨论(0)
  • 2021-01-30 11:15

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

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

    Credit to: Majid Jabrayilov

    0 讨论(0)
提交回复
热议问题