簡體   English   中英

從 Picker 切換到 Image 視圖會導致 SwiftUI 中的索引超出范圍錯誤

[英]Toggling from Picker to Image view causes an index out of range error in SwiftUI

我有一個視圖,它使用一個按鈕在選擇器和作為選擇器選擇結果的圖像之間切換。 當從圖像快速切換到選擇器並立即返回時,我遇到崩潰並出現以下錯誤:

Swift/ContiguousArrayBuffer.swift:600: Fatal error: Index out of range

較慢地切換不會導致這種情況,也不會在另一個方向切換(選擇器到圖像並返回)。 這是有問題的代碼:

import SwiftUI

struct ContentView: View {
    @State private var showingPicker = false
    @State private var currentNum = 0
    @State private var numbers: [Int] = [1, 2, 3, 4, 5]
    
    
    var body: some View {
        
            VStack(spacing: 15) {
                Spacer()
                if showingPicker {
                    Picker("Number", selection: $currentNum) {
                        ForEach(0..<numbers.count, id: \.self) {
                            Text("\($0)")
                        }
                    }
                    .pickerStyle(.wheel)
                } else {
                    Image(systemName: "\(currentNum).circle")
                }
                
                Spacer()
                
                Button("Toggle") {
                    showingPicker = !showingPicker
                }
                
            }
    }
}

代碼以其他方式工作。 我是 SwiftUI 的新手,所以我仍然在思考如何創建/銷毀視圖。 我嘗試更改屬性的順序,認為數組可能在重新創建之前被訪問(如果發生這種情況),但這沒有效果。 我還嘗試了ForEach(numbers.indices)而不是ForEach(0..<numbers.count) ,但結果相同。

**編輯

我現在想出了一個權宜之計。 我添加了@State private var buttonEnabled = true並修改了按鈕:

Button("Toggle") {
    showingPicker = !showingPicker
    buttonEnabled = false
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
        buttonEnabled = true
    }
}
.disabled(buttonEnabled == false)

去抖動它。 我仍然想弄清楚問題並進行真正的修復。

**編輯

根據評論,我修改了代碼,將數組索引排除在等式之外,以更好地反映我正在從事的實際項目。 該代碼仍然有效,但快速切換將導致完全相同的崩潰和錯誤。 它似乎也只發生在使用 .wheel 風格的選擇器時,其他選擇器 styles 沒有這種行為。

private let icons = ["ear", "cube", "eye", "forward", "gear"]

struct ContentView: View {
    @State private var showingPicker = false
    @State private var currentIcon = icons[0]
    
    var body: some View {
        VStack(spacing: 15) {
            Spacer()
            if showingPicker {
                Picker("Icon", selection: $currentIcon) {
                    ForEach(icons, id: \.self) {
                        Image(systemName: $0)
                    }
                }
                .pickerStyle(.wheel)
            } else {
                Image(systemName: currentIcon)
            }
            
            Spacer()
            
            Button("Toggle") {
                showingPicker.toggle()
            }
        }
    }
}

ForEach 不是 for 循環,您不能使用array.countid:\.self您需要使用真實的 id 參數或使用Identifiable協議。

但是,如果您只需要數字,它也支持:

ForEach(0..<5) { i in

只要您不嘗試使用i查找數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM