SwiftUI 中的“身份”是啥意思以及我们如何更改某物的“身份”
Posted
技术标签:
【中文标题】SwiftUI 中的“身份”是啥意思以及我们如何更改某物的“身份”【英文标题】:What does 'identity' mean in SwifUI and how do we change the 'identity' of somethingSwiftUI 中的“身份”是什么意思以及我们如何更改某物的“身份” 【发布时间】:2020-04-13 07:50:04 【问题描述】:我是 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
我对@987654323@ 部分特别感兴趣。由于我希望连续显示警报,如果我能够以某种方式更改“身份”,我将能够实现我想要的功能 - 即让系统关闭当前显示的警报并将旧警报替换为新警报(背靠背)。
如果有人能向我解释什么是“身份”以及我如何改变某物的“身份”,我将不胜感激。
(或者,如果您知道一种更好的方式来连续显示警报,这也将非常有帮助。)
提前致谢!
【问题讨论】:
【参考方案1】:在下面找到按项目使用警报的演示。以及一些关于改变身份的调查结果记录在案。
您发现尝试通过用户交互激活的示例(通过点击行)警报工作正常,但是如文档所述,以编程方式更改身份似乎还不稳定,但警报确实已更新。
使用 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")))
【讨论】:
非常感谢。我想知道为什么当我尝试更改身份时我的应用程序不断崩溃。如果这种方法不稳定,我想我必须找到另一种方法来连续弹出警报。非常感谢!【参考方案2】:注意这个方法需要Binding<Item?>
,而Item
应该是Identifiable
。对于Binding<Item?>
参数,您应该传入一个“事实来源”来控制显示的警报的外观,或者是否显示警报。当这个事实来源发生变化(即变成其他东西)时,视图将更新警报。
但是问题来了,SwiftUI 怎么知道在你的模型上下文中“改变”是什么意思?假设Item
是您编写的Person
类。 Person
有一个 name
和 age
。你的工作是告诉 SwiftUI,“Person
在名称更改时会变成一个完全不同的人”。 (当然,你可以对这里的“人变”有其他定义。这个定义只是一个例子。)
struct Person : Identifiable
var id: String
name
let name: String
let age: Int
这就是为什么Item
必须是Identifiable
。 Item.id
因此是“身份”。
请注意,Identifiable
与 Equatable
不同,Identifiable
提出的问题是“是什么让这个人与众不同?”而Equatable
询问“您希望==
给出什么结果?”。另一个例子见this。
我们如何改变某物的“身份”?
只需更改您传入的绑定(例如,设置绑定所基于的@State
),使其id
发生变化。
【讨论】:
非常感谢您的澄清。我尝试更改我传入的绑定,但这似乎仍然没有按照我想要的方式工作。正如另一个答案所暗示的那样,也许以编程方式更改身份还不是稳定的。我想我得另寻他法了。还是非常感谢!以上是关于SwiftUI 中的“身份”是啥意思以及我们如何更改某物的“身份”的主要内容,如果未能解决你的问题,请参考以下文章