簡體   English   中英

SwiftUI static 列出奇怪的重用行為

[英]SwiftUI static List weird reuse behavior

我在使用 SwiftUI 中的 static 列表時遇到了一個奇怪的行為。 我無法確定這是 SwiftUI 錯誤還是我做錯了什么。 我有一個非常簡單的列表,如下所示:

var body: some View {
    List {
        SettingsPickerView<TrigonometryUnit>(title: "Trigonometry Units", selection: $viewModel.trigonometryUnitIndex, items: TrigonometryUnit.allCases)
        SettingsPickerView<DecimalSeparator>(title: "Decimal Separator", selection: $viewModel.decimalSeparatorIndex, items: DecimalSeparator.allCases)
        SettingsPickerView<GroupingSeparator>(title: "Grouping Separator", selection: $viewModel.groupingSeparatorIndex, items: GroupingSeparator.allCases)
        SettingsPickerView<ExponentSymbol>(title: "Exponent Symbol", selection: $viewModel.exponentSymbolIndex, items: ExponentSymbol.allCases)
    }
}

List 的每個單元格如下所示:

struct SettingsPickerView<T: Segmentable>: View {

    let title: String
    @Binding var selection: Int
    let items: [T]

    var body: some View {
        Section(header: Text(title)) {
            ForEach(items.indices) { index in
                self.cell(for: self.items[index], index: index)
            }
        }
    }

    private func cell(for item: T, index: Int) -> some View {
        print(title, item.title, items.map({ $0.title }))
        return Button(action: {
            self.selection = index
        }, label: {
            HStack {
                Text(item.title)
                Spacer()
                if index == self.selection {
                    Image(systemName: "checkmark")
                        .font(.headline)
                        .foregroundColor(.rpnCalculatorOrange)
                }
            }
        })
    }

}

最后,這是一個Segmentable object 的樣子:

enum GroupingSeparator: Int, CaseIterable {

    case defaultSeparator
    case space
    case comma

}

extension GroupingSeparator: Segmentable {

    var id: String {
        switch self {
        case .defaultSeparator:
            return "groupingSeparator.default"
        case .space:
            return "groupingSeparator.space"
        case .comma:
            return "groupingSeparator.comma"
        }
    }

    var title: String {
        switch self {
        case .defaultSeparator:
            return "Default"
        case .space:
            return "Space"
        case .comma:
            return "Comma"
        }
    }

}

加載SettingsView時。 一切看起來都很好。 但是,一旦我開始滾動並實例化其他一些單元格,就會顯示一些單元格,但不是正確的單元格。 這是一些截圖和日志。

加載視圖后,沒有滾動,屏幕如下所示:

在此處輸入圖像描述

但是,我在控制台上得到的東西很奇怪,並且不遵循在主視圖中編寫的SettingsPickerView的順序:

Trigonometry Units Radians ["Radians", "Degrees"] <-- Fine
Trigonometry Units Degrees ["Radians", "Degrees"] <-- Fine
Decimal Separator Default ["Default", "Dot", "Comma"] <-- Fine
Decimal Separator Default ["Default", "Dot", "Comma"] <-- Fine
Trigonometry Units Degrees ["Radians", "Degrees"] <-- Not expected. Should be Grouping Separator
Trigonometry Units Radians ["Radians", "Degrees"] <-- Not expected. Should be Grouping Separator

第二部分沒問題並正確顯示:

在此處輸入圖像描述

但是第三部分完全斷了:

在此處輸入圖像描述

第三部分正確顯示其標題,但顯示第一部分的一些數據。 我嘗試向單元格中的按鈕添加標識符,因為問題看起來像 SwiftUI 無法識別正確的數據。 但是向按鈕添加標識符會破壞綁定,並且復選框不再更改。

private func cell(for item: T, index: Int) -> some View {
    print(title, item.title, items.map({ $0.title }))
    return Button(action: {
        self.selection = index
    }, label: {
        HStack {
            Text(item.title)
            Spacer()
            if index == self.selection {
                Image(systemName: "checkmark")
                    .font(.headline)
                    .foregroundColor(.rpnCalculatorOrange)
            }
        }
    })
        .id(UUID().uuidString) // This solve the display issue but broke the binding.
}

以前有人經歷過這樣的事情嗎?

在此先感謝您的幫助。

這是固定的代碼塊(由於使用的索引只有 List 被混淆並重用行,因此解決方案是使行可被項目識別)。

用 Xcode 11.4 測試

struct PickerView<T: Segmentable>: View {

    // ... other code here

    var body: some View {
        Section(header: Text(title)) {
            // Corrected section construction !!
            ForEach(Array(items.enumerated()), id: \.element.id) { index, _ in
                self.cell(for: self.items[index], index: index)
            }
        }
    }

    // ... other code here

暫無
暫無

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

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