绑定值源已删除 [英] Binding Value Source Deleted

查看:61
本文介绍了绑定值源已删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For some reason I get an index out of bounds error when using state (with an array) and binding with one of its values. In general there is no problem adding more values to the array. However when you try and delete a value, you get an index out of bound error.

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

This is a simplified version the problem I have in my own project.

在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

Try the sample below in SwiftUI. Simply hold one of the circle to try and delete one! When it deletes there will be a Swift error: 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之一约束.删除后,视图不再有权访问该值,从而触发越界错误.

I believe the error comes from the fact that the value being deleted is being bound by one of the CustomView's value. On deletion the view no longer has access to that value, triggering the out of bounds error.

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()
    }
}

推荐答案

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

There are two reasons in this case: constant ForEach, and refresh racing with direct biding.

这是一个修复崩溃并按预期工作的解决方案.在Xcode 11.4/iOS 13.4上进行了测试.

Here is a solution that fixes crash and works as expected. Tested with 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()
            }
        }
        }
    }
}

这篇关于绑定值源已删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆