[英]SwiftUI View - viewDidLoad()?
在視圖加載后嘗試加載圖像,驅動視圖的模型對象(參見下面的 MovieDetail)有一個 urlString。 因為 SwiftUI View
元素沒有生命周期方法(並且沒有視圖控制器驅動事物)處理這個問題的最佳方法是什么?
我遇到的主要問題是無論我嘗試以哪種方式解決問題(綁定對象或使用狀態變量),我的視圖在urlString
之前都沒有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)
}
}
}
}
提前致謝。
我希望這是有幫助的。 我找到了一篇博文,其中討論了在 onAppear 上為導航視圖做事。
想法是您將服務烘焙到 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 = []
}
}
}
}
}
信用:馬吉德·賈布拉伊洛夫
我們可以使用視圖修飾符來實現這一點。
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?()
}
}
}
}
View
擴展:extension View {
func onLoad(perform action: (() -> Void)? = nil) -> some View {
modifier(ViewDidLoadModifier(perform: action))
}
}
struct SomeView: View {
var body: some View {
VStack {
Text("HELLO!")
}.onLoad {
print("onLoad")
}
}
}
為 Xcode 11.2、Swift 5.0 全面更新
我認為viewDidLoad()
正好等於在主體閉包中實現。
SwiftUI 以onAppear()
和onDisappear()
的形式為我們提供了 UIKit 的viewDidAppear()
和viewDidDisappear()
等價物。 您可以將任何代碼附加到您想要的這兩個事件上,SwiftUI 會在它們發生時執行它們。
例如,這將創建兩個使用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!")
}
}
}
參考: https : //www.hackingwithswift.com/quick-start/swiftui/how-to-respond-to-view-lifecycle-events-onappear-and-ondisappear
我正在使用init()
代替。 我認為onApear()
不是viewDidLoad()
的替代品。 因為 onApear 在您的視圖出現時被調用。 由於您的視圖可以多次出現,因此它與調用一次的viewDidLoad
沖突。
想象一下有一個TabView
。 通過在頁面上滑動,onApear() 被多次調用。 然而 viewDidLoad() 只被調用一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.