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

我对@9​​87654323@ 部分特别感兴趣。由于我希望连续显示警报,如果我能够以某种方式更改“身份”,我将能够实现我想要的功能 - 即让系统关闭当前显示的警报并将旧警报替换为新警报(背靠背)。

如果有人能向我解释什么是“身份”以及我如何改变某物的“身份”,我将不胜感激。

(或者,如果您知道一种更好的方式来连续显示警报,这也将非常有帮助。)

提前致谢!

【问题讨论】:

【参考方案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&lt;Item?&gt;,而Item 应该是Identifiable。对于Binding&lt;Item?&gt; 参数,您应该传入一个“事实来源”来控制显示的警报的外观,或者是否显示警报。当这个事实来源发生变化(即变成其他东西)时,视图将更新警报。

但是问题来了,SwiftUI 怎么知道在你的模型上下文中“改变”是什么意思?假设Item 是您编写的Person 类。 Person 有一个 nameage。你的工作是告诉 SwiftUI,“Person 在名称更改时会变成一个完全不同的人”。 (当然,你可以对这里的“人变”有其他定义。这个定义只是一个例子。)

struct Person : Identifiable 
    var id: String 
        name
    

    let name: String
    let age: Int

这就是为什么Item 必须是IdentifiableItem.id 因此是“身份”。

请注意,IdentifiableEquatable 不同,Identifiable 提出的问题是“是什么让这个人与众不同?”而Equatable 询问“您希望== 给出什么结果?”。另一个例子见this。

我们如何改变某物的“身份”?

只需更改您传入的绑定(例如,设置绑定所基于的@State),使其id 发生变化。

【讨论】:

非常感谢您的澄清。我尝试更改我传入的绑定,但这似乎仍然没有按照我想要的方式工作。正如另一个答案所暗示的那样,也许以编程方式更改身份还不是稳定的。我想我得另寻他法了。还是非常感谢!

以上是关于SwiftUI 中的“身份”是啥意思以及我们如何更改某物的“身份”的主要内容,如果未能解决你的问题,请参考以下文章

javascript中的双括号是啥意思以及如何访问它们

Swiftui 中 init() 中变量前的下划线是啥意思?

币圈令牌是啥意思

以管理员身份运行是啥意思?

品质 oba是啥意思

开源项目中的/dist目录是啥意思?