取消选择 SwiftUI 列表中的项目会使应用程序崩溃

Posted

技术标签:

【中文标题】取消选择 SwiftUI 列表中的项目会使应用程序崩溃【英文标题】:Unselecting an item on a SwiftUI list crashes the app 【发布时间】:2020-05-30 23:29:23 【问题描述】:

我在使用可选绑定的 SwiftUI 时遇到了问题,基本上它是 macOS 上的一个 List,一旦选择了一个项目,我就会在其中添加一个 DetailView,如果没有选择就添加一个 Text。

当我打开应用程序时,它很好,出现文本,然后我添加一些项目并选择它,也正常工作,出现 DetailView,但是一旦我在表格外部单击,取消选择它,它就会崩溃。更难的是,我有条件检查 nil,这就是它第一次起作用的原因。

我猜 DetailView 会保留对 selectedItem 的引用,一旦它设置为 nil 就会崩溃,但我认为一旦 State 属性发生更改,应该刷新整个主体,这将从内存中删除以前的 DetailView 而不会调用新的,对吧?

代码如下:

import SwiftUI

struct DetailView: View 
    @Binding var text: String

    var body: some View 
        TextField("123", text: self.$text)
    


struct ContentView: View 
    @State var text = ""
    @State var items = [String]()
    @State var selectedItem: String? = nil

    var body: some View 
        VStack 
            HStack 
                VStack(alignment: .leading, spacing: 0) 
                    List(selection: $selectedItem) 
                        ForEach(items, id: \.self)  item in
                            Text(item)
                        
                    
                    HStack(spacing: 0) 
                        Button(action: 
                            self.items.append(UUID().uuidString)
                        , label: 
                            Text("Add")
                        )
                        Button(action: 
                            if let item = self.selectedItem 
                                self.items.remove(at: self.items.firstIndex(of: item)!)
                            
                            self.selectedItem = nil
                        , label: 
                            Text("Remove")
                        ).disabled(selectedItem == nil)
                    
                
                if selectedItem != nil 
                    DetailView(text: Binding($selectedItem)!)
                 else 
                    Text("Add an item")
                
            
            .tabItem 
                Text("Test")
            
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    


【问题讨论】:

【参考方案1】:

我猜 DetailView 保留了对 selectedItem 的引用,并且 一旦设置为零就会崩溃,但我认为整个身体应该是 更改 State 属性后刷新,这将删除 从内存中调用前一个 DetailView 而不是调用一个新的,对吧?

更新的顺序没有定义,所以我会在上面回答否。

这里有一个解决方案。使用 Xcode 11.4 / ios 13.4 测试

if selectedItem != nil 
    DetailView(text: Binding(get: self.selectedItem ?? "", 
                             set: self.selectedItem = $0))
 else 
    Text("Add an item")

【讨论】:

以上是关于取消选择 SwiftUI 列表中的项目会使应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 未取消选择列表项

SwiftUI:选择列表中的项目后更新数据

在 SwiftUI 列表中选择多个项目

选择添加到 SwiftUI 列表的新项目

在不使用导航链接的情况下获取 SwiftUI 列表中的选定项目

选择/取消选择多个列表框中的多个项目