已删除绑定值源

问题描述 投票:0回答:1

由于某种原因,在使用状态(带有数组)并绑定其值之一时,出现索引超出范围的错误。通常,向数组添加更多值没有问题。但是,当您尝试删除一个值时,您将获得索引超出范围的错误。

这是我自己的项目中遇到的问题的简化版本。

尝试下面的SwiftUI示例。只需按住一个圈子即可尝试删除一个圈子!删除时会出现Swift错误:Fatal error: Index out of range: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444

我相信该错误来自以下事实:要删除的值受CustomViewvalue之一约束。删除后,视图不再有权访问该值,从而触发越界错误。

import SwiftUI

struct Test: View {
    @State var values: [Int] = [0, 1, 1, 1]
    var totalBalls: Int {
        return values.count
    }
    var body: some View {
        HStack {
            Text("\(totalBalls)")
        VStack {
            ForEach(0..<values.count, id: \.self) { i in
                CustomView(value: self.$values[i])
            }
            .onLongPressGesture {
                self.values.removeLast() //this line causes an error!
            }
        }
        }
    }
}

struct CustomView: View {
    @Binding var value: Int
    var body: some View {
        ZStack {
            Circle()
            Text("\(value)").foregroundColor(Color.orange)
        }.onTapGesture {
            self.value+=1
        }
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: some View {
        Test()
    }
}

swift binding swiftui
1个回答
0
投票

在这种情况下,有两个原因:ForEach保持不变,并通过直接出价刷新竞速。

这里是解决崩溃并按预期工作的解决方案。经过Xcode 11.4 / iOS 13.4的测试。

struct TestDeleteLast: View {
    @State var values: [Int] = [0, 1, 1, 1]
    var totalBalls: Int {
        return values.count
    }
    var body: some View {
        HStack {
            Text("\(totalBalls)")
        VStack {
            // use index as id in ForEach
            ForEach(Array(values.enumerated()), id: \.0.self) { i, _ in
                CustomView(value: Binding(   // << use proxy binding !!
                    get: { self.values[i] },
                    set: { self.values[i] = $0 }))
            }
            .onLongPressGesture {
                self.values.removeLast()
            }
        }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.