programing

Swift UI 보기 - viewDidLoad()?

stoneblock 2023. 9. 16. 08:30

Swift UI 보기 - viewDidLoad()?

뷰가 로드된 후 이미지를 로드하려고 하면 뷰를 구동하는 모델 개체(아래 MovieDetail 참조)에 urlString이 있습니다.왜냐하면 스위프트 UI는View요소에 라이프 사이클 방법이 없습니다(그리고 뷰 컨트롤러가 작동하지 않음). 이를 처리하는 가장 좋은 방법은 무엇입니까?

문제를 해결하려는 방법(객체 바인딩 또는 상태 변수 사용)에 상관없이 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. 만들다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. 만들다View확장명:
extension View {

    func onLoad(perform action: (() -> Void)? = nil) -> some View {
        modifier(ViewDidLoadModifier(perform: action))
    }

}
  1. 다음과 같이 사용:
struct SomeView: View {
    var body: some View {
        VStack {
            Text("HELLO!")
        }.onLoad {
            print("onLoad")
        }
    }
}

이것이 도움이 되었으면 좋겠습니다.탐색 보기에 표시하기에서 작업에 대해 이야기하는 블로그 게시물을 찾았습니다.

서비스를 Bindable Object로 만들고 보기에 있는 업데이트를 구독하는 것이 좋습니다.

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

크레딧: 마지드 자바릴로프

Xcode 11.2, Swift 5.0용으로 완전히 업데이트됨

제 생각에는.viewDidLoad()차체 폐쇄 장치에서 구현하기에 딱 맞먹습니다.
스위프트 UI는 UIKit과 동등한 기능을 제공합니다.viewDidAppear()그리고.viewDidDisappear()의 형식으로onAppear()그리고.onDisappear(). 이 두 이벤트에 원하는 코드를 첨부할 수 있습니다. 그리고 스위프트.UI는 발생할 때 실행합니다.

예를 들어 다음을 사용하는 두 개의 보기를 만듭니다.onAppear()그리고.onDisappear()둘 사이를 이동할 수 있는 탐색 링크와 함께 메시지를 인쇄합니다.

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

사용하고 있습니다.init()대신.생각합니다onApear()의 대안이 아닙니다.viewDidLoad(). 왜냐하면 당신의 보기가 나타날 때 피어가 호출되기 때문입니다.보기가 여러 번 표시될 수 있으므로 다음과 충돌합니다.viewDidLoad한 번이라고 합니다.

상상해보세요.TabView. 피어()의 페이지를 스와이프하여 여러 번 호출됩니다.그러나 viewDidLoad()는 한 번만 호출됩니다.

언급URL : https://stackoverflow.com/questions/56496359/swiftui-view-viewdidload