试图在视图加载后加载图像,驱动视图的模型对象(参见下面的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)
}
}
}
}提前谢谢。
发布于 2019-06-07 15:01:37
我希望这是有帮助的。我找到了博客,它谈到了如何为导航视图做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 = []
}
}
}
}
}贷项: Majid Jabrayilov
发布于 2020-10-23 07:41:21
我们可以使用视图修饰符来实现这一点。
ViewModifierstruct 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")
}
}
}发布于 2020-01-09 06:52:36
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://stackoverflow.com/questions/56496359
复制相似问题