我正在遵循“Thinking in Swift UI”一书的示例。
我正在创建一个可观察对象
final class Contact: ObservableObject, Identifiable {
let id = UUID()
@Published var name: String
@Published var city: String
@Published var profile: String
init(name: String, city: String, profile: String) {
self.name = name
self.city = city
self.profile = profile
}
}
Run Code Online (Sandbox Code Playgroud)
内容视图被定义为选择联系人的按钮列表。它将联系人存储为普通数组属性
struct ContentView: View {
@State var selection: Contact?
var contacts: [Contact]
var body: some View {
HStack {
ForEach(contacts) { contact in
Button(contact.name) {
self.selection = contact
}
}
}
if let c = selection {
Detail2(contact: c)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里我们有详细信息视图,它调用 id 修饰符来更改视图的标识,并据称使“onAppear”再次被调用 - 这是行不通的
struct Detail: View {
@ObservedObject var contact: Contact
@StateObject var loader = ImageLoader()
var body: some View {
HStack {
loader.imageView
VStack {
Text(contact.name).bold()
Text(contact.city)
}
}
.id(contact.id)
.onAppear {
loader.load(image: contact.profile)
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里我嘲笑了 Loader
class ImageLoader: ObservableObject {
var image: String = ""
init() {
print("Initializer of Image Loader was called")
}
func load(image: String) {
print("Brrr.... loading image")
print("The image is: \(image)")
self.image = image
}
}
Run Code Online (Sandbox Code Playgroud)
该应用程序被定义为内容视图,它传递联系人数组:
@main
struct SwiftUILearning2App: App {
var body: some Scene {
WindowGroup {
ContentView(contacts: [ Contact(name: "name1", city: "city1", profile: "profile_1"),
Contact(name: "name2", city: "city2", profile: "profile_2")])
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么在分配新联系人时不调用 onAppear - 实际上 load.loader( ) 不会被调用?根据书上的.id(contact.id)修改器调用Detail View应该可以使onAppear再次被调用。
在没有修饰符的示例之后,.id(contact.id书中指出:
“第一次尝试时,这似乎有效,但是当我们更改联系人对象(例如,通过选择不同的人)时,视图永远不会重新加载图像。解决此问题的最简单方法是告诉 SwiftUI 它应该更改视图的身份:”
这是完整代码的链接: https://gist.github.com/pbrewczynski/63f2dfdba96dec2efcf7d81d304622f6
小智 7
根据 swiftUI 文档:
\n\n\n当id参数指定的代理值发生变化时,视图\xe2\x80\x94的标识(例如,它的状态\xe2\x80\x94)将被重置。
\n
该视图不会调用 onAppear() 方法,因为它没有再次创建,更改其状态和参数。\n我的建议是调用 onChange() 方法:
\n .onChange(of: contact) { newValue in\n loader.load(image: newValue.profile)\n }\nRun Code Online (Sandbox Code Playgroud)\n解决方案有很多,但id修饰符通常用于:
\n这里有一篇文章有帮助
\n| 归档时间: |
|
| 查看次数: |
4492 次 |
| 最近记录: |