首页 > 解决方案 > 如何在 swiftUI 列表中更改复杂数据源

问题描述

当我更改数据源时应用程序崩溃,例如点击 APIView 中的“更改数据”按钮或删除 QueryParametersView.list 中的项目

控制台日志:

此类“SwiftUI.AccessibilityNode”不是已知的可序列化元素,将其作为可访问性元素返回可能会导致崩溃

致命错误:索引超出范围:文件 /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift,第 444 行

class URLComponentsModel: ObservableObject {
    @Published var urlComponents = URLComponents.init()
    var urlQueryItems: [URLQueryItem] {
        get {
            urlComponents.queryItems ?? [URLQueryItem].init()
        }
        set {
            urlComponents.queryItems = newValue
        }
    }
}

struct APIView: View {
    @ObservedObject var urlComponentsModel = URLComponentsModel.init()
    var body: some View {
        Button.init("change data") {
            self.urlComponentsModel.urlComponents.queryItems?.removeFirst()
        }
        QueryParametersView.init(parameters: self.$urlComponentsModel.urlQueryItems)
    }
}

struct QueryParametersView: View {
    @Binding var parameters: [URLQueryItem]
    
    var body: some View {
        List {
            ForEach(self.parameters.indices, id: \.self) { i in
                    HStack {
                        ParameterView.init(urlQueryItem: self.$parameters[i])
                        Text.init("delete")
                            .onTapGesture {
                                self.parameters.remove(at: i)
                        }
                    }
            }
                .onDelete { indices in
                    indices.forEach {
                        self.parameters.remove(at: $0)
                }
        }
    }
}

struct ParameterView: View {
    @Binding var urlQueryItem: URLQueryItem
    var body: some View {
        ZStack {
            ...
            HStack {
                ...
                if self.urlQueryItem.value != nil {
                    TextField("Value", text: Binding.init(get: {
                        (self.urlQueryItem.value ?? "")
                    }, set: { (value) in
                        self.urlQueryItem.value = value
                    }))
                }
            }
        }
    }
}

为什么?有人帮我吗?

标签: iosbindingswiftuioptionalswiftui-list

解决方案


删除第一()

它说

集合不能为空。

如果调用 removeFirst 时集合为空,则应用程序会因索引超出范围而崩溃。


推荐阅读