'identity' 在 SwiftUI 中是什么意思以及我们如何更改某些内容的 'identity'
What does 'identity' mean in SwifUI and how do we change the 'identity' of something
我是 SwiftUI 的新手,我在连续显示警报时遇到问题。
.alert(item:content:)
修饰符的描述在它的定义中写了这个:
/// Presents an alert.
///
/// - Parameters:
/// - item: A `Binding` to an optional source of truth for the `Alert`.
/// When representing a non-nil item, the system uses `content` to
/// create an alert representation of the item.
///
/// If the identity changes, the system will dismiss a
/// currently-presented alert and replace it by a new alert.
///
/// - content: A closure returning the `Alert` to present.
public func alert<Item>(item: Binding<Item?>, content: (Item) -> Alert) -> some View where Item : Identifiable
我对 If the identity changes, the system will dismiss a currently-presented alert and replace it by a new alert
部分特别感兴趣。由于我希望连续显示警报,如果我能够以某种方式更改 'identity',我将能够实现我想要的功能 - 让系统关闭当前 -显示警报并用新警报替换旧警报(背靠背)。
如果有人能向我解释 'identity' 是什么以及我如何更改某些内容的 'identity',我将不胜感激。
(或者,如果您知道一种更好的连续显示警报的方法,那也会非常有帮助。)
提前致谢!
请注意此方法如何需要 Binding<Item?>
,而 Item
应该是 Identifiable
。对于 Binding<Item?>
参数,您应该传入一个 "source of truth" 来控制显示的警报的外观,或者是否显示警报。当这个真相来源发生变化时(即变成其他东西),视图将更新警报。
但这就是问题所在,SwiftUI 如何知道 "change" 在模型上下文中的含义?假设 Item
是您编写的 Person
class。 Person
有一个 name
和 age
。告诉 SwiftUI 是你的工作,"a Person
becomes a totally different person when its name changes"。 (当然,您可以在这里对 "a person changes" 的含义有一些其他定义。这个定义只是一个例子。)
struct Person : Identifiable {
var id: String {
name
}
let name: String
let age: Int
}
这就是为什么 Item
必须是 Identifiable
。 Item.id
因此是 "identity"。
请注意 Identifiable
与 Equatable
不同,因为 Identifiable
提出问题 "what makes this person a different person?" 而 Equatable
提出 "what result would you want ==
to give?"。另一个例子见 this。
how do we change the 'identity' of something?
只需更改您传入的绑定(例如,设置绑定所基于的 @State
),使其 id
发生变化。
在下面找到按项目使用警报的演示。以及一些关于改变身份的调查结果记录在案。
正如您发现通过用户交互激活的示例(通过点击行)进行试验一样,警报工作正常,但以编程方式更改身份,如文档所述,似乎还不稳定,但警报确实已更新。
测试 Xcode 11.4 / iOS 13.4
struct SomeItem: Identifiable { // identifiable item
var id: Int // identity
}
struct DemoAlertOnItem: View {
@State private var selectedItem: SomeItem? = nil
var body: some View {
VStack {
ScrollView (.vertical, showsIndicators: false) {
ForEach (0..<5) { i in
Text("Item \(i)").padding()
.onTapGesture {
self.selectedItem = SomeItem(id: i)
// below simulate change identity while alert is shown
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.selectedItem = nil // works !!
// self.selectedItem?.id = 100 // crash !!
// self.selectedItem = SomeItem(id: 100) // crash !!
}
}
}
}
}
.alert(item: self.$selectedItem) { item in
Alert(title: Text("Alert"), message: Text("For item \(item.id)"), dismissButton: .default(Text("OK")))
}
}
}
我是 SwiftUI 的新手,我在连续显示警报时遇到问题。
.alert(item:content:)
修饰符的描述在它的定义中写了这个:
/// Presents an alert.
///
/// - Parameters:
/// - item: A `Binding` to an optional source of truth for the `Alert`.
/// When representing a non-nil item, the system uses `content` to
/// create an alert representation of the item.
///
/// If the identity changes, the system will dismiss a
/// currently-presented alert and replace it by a new alert.
///
/// - content: A closure returning the `Alert` to present.
public func alert<Item>(item: Binding<Item?>, content: (Item) -> Alert) -> some View where Item : Identifiable
我对 If the identity changes, the system will dismiss a currently-presented alert and replace it by a new alert
部分特别感兴趣。由于我希望连续显示警报,如果我能够以某种方式更改 'identity',我将能够实现我想要的功能 - 让系统关闭当前 -显示警报并用新警报替换旧警报(背靠背)。
如果有人能向我解释 'identity' 是什么以及我如何更改某些内容的 'identity',我将不胜感激。
(或者,如果您知道一种更好的连续显示警报的方法,那也会非常有帮助。)
提前致谢!
请注意此方法如何需要 Binding<Item?>
,而 Item
应该是 Identifiable
。对于 Binding<Item?>
参数,您应该传入一个 "source of truth" 来控制显示的警报的外观,或者是否显示警报。当这个真相来源发生变化时(即变成其他东西),视图将更新警报。
但这就是问题所在,SwiftUI 如何知道 "change" 在模型上下文中的含义?假设 Item
是您编写的 Person
class。 Person
有一个 name
和 age
。告诉 SwiftUI 是你的工作,"a Person
becomes a totally different person when its name changes"。 (当然,您可以在这里对 "a person changes" 的含义有一些其他定义。这个定义只是一个例子。)
struct Person : Identifiable {
var id: String {
name
}
let name: String
let age: Int
}
这就是为什么 Item
必须是 Identifiable
。 Item.id
因此是 "identity"。
请注意 Identifiable
与 Equatable
不同,因为 Identifiable
提出问题 "what makes this person a different person?" 而 Equatable
提出 "what result would you want ==
to give?"。另一个例子见 this。
how do we change the 'identity' of something?
只需更改您传入的绑定(例如,设置绑定所基于的 @State
),使其 id
发生变化。
在下面找到按项目使用警报的演示。以及一些关于改变身份的调查结果记录在案。
正如您发现通过用户交互激活的示例(通过点击行)进行试验一样,警报工作正常,但以编程方式更改身份,如文档所述,似乎还不稳定,但警报确实已更新。
测试 Xcode 11.4 / iOS 13.4
struct SomeItem: Identifiable { // identifiable item
var id: Int // identity
}
struct DemoAlertOnItem: View {
@State private var selectedItem: SomeItem? = nil
var body: some View {
VStack {
ScrollView (.vertical, showsIndicators: false) {
ForEach (0..<5) { i in
Text("Item \(i)").padding()
.onTapGesture {
self.selectedItem = SomeItem(id: i)
// below simulate change identity while alert is shown
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.selectedItem = nil // works !!
// self.selectedItem?.id = 100 // crash !!
// self.selectedItem = SomeItem(id: 100) // crash !!
}
}
}
}
}
.alert(item: self.$selectedItem) { item in
Alert(title: Text("Alert"), message: Text("For item \(item.id)"), dismissButton: .default(Text("OK")))
}
}
}