[英]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.