0

我在 SwiftUI 中为正在开发的应用程序创建了一个自定义选择按钮视图。我一生都无法弄清楚为什么有时按钮什么都不做 - 它总是最后 x 个按钮不起作用(这让我认为这与 swift ui 的 10 视图限制有关,我被告知在使用 for each 循环时这不是问题)。

有时它会按预期工作,而另一些则会切断最后 x 个按钮。虽然当它切断按钮时,它在不同的模拟器和物理设备之间是一致的。有人能看出这里有什么问题吗?

我是 SwiftUI 的新手,所以可能很简单......

    
    @EnvironmentObject var QuestionManager: questionManager
    
    var listItems: [String]
    @State var selectedItem: String = ""
    
    var body: some View {
        
        GeometryReader {geom in
            ScrollView{
                VStack{
                    ForEach(Array(listItems.enumerated()), id: \.offset){ item in
                        Button(action: {
                            if (selectedItem != item.element) {
                                selectedItem = item.element
                            } else {
                                selectedItem = ""
                                QuestionManager.tmpAnswer = ""
                            }
                            
                        }, label: {
                            GeometryReader { g in
                                Text("\(item.element)")
                                    .font(.system(size: g.size.width/22))
                                    .fixedSize(horizontal: false, vertical: true)
                                    .foregroundColor(.black)
                                    .lineLimit(2)
                                    .frame(width: g.size.width, height: g.size.height)
                                    .minimumScaleFactor(0.5)
                                    .background(
                                        Rectangle()
                                            .fill((item.element == selectedItem) ? Color(.green) : .white)
                                            .frame(width: g.size.width, height: g.size.height)
                                            .border(Color.gray)
                                    ).scaledToFit()
                            }
                            .frame(width: geom.size.width*0.92, height: 45)
                        }).disabled((Int(QuestionManager.answers.year) == Calendar.current.component(.year, from: Date())) ? validateMonth(month: item.offset) : false)
                    }
                }
                .frame(width: geom.size.width)
            }
        }
    }
} ```
4

1 回答 1

0

正如@Yrb 提到的,enumerated()在循环中使用不是一个很好的选择ForEachlistItems重复元素可能会使您的问题更加复杂。您可能希望重组代码,例如使用专用项目结构的这种方法,在我的测试中效果很好:

struct MyItem: Identifiable, Equatable {
    let id = UUID()
    var name = ""
    
    init(_ str: String) {
        self.name = str
    }

    static func == (lhs: MyItem, rhs: MyItem) -> Bool {
       lhs.id == rhs.id
    }
}

struct ContentView: View {
    @EnvironmentObject var QuestionManager: questionManager
    // for testing
    var listItems: [MyItem] = [MyItem("1"),MyItem("2"),MyItem("3"),MyItem("4"),MyItem("6"),MyItem("7"),MyItem("8"),MyItem("9")]
    
    @State var selectedItem: MyItem? = nil
     
    var body: some View {
        GeometryReader {geom in
            ScrollView{
                VStack{
                    ForEach(listItems){ item in
                        Button(action: {
                            if (selectedItem != item) {
                                selectedItem = item
                            } else {
                                selectedItem = nil
                                QuestionManager.tmpAnswer = ""
                            }
                        }, label: {
                            GeometryReader { g in
                                Text(item.name)
                                    .font(.system(size: g.size.width/22))
                                    .fixedSize(horizontal: false, vertical: true)
                                    .foregroundColor(.black)
                                    .lineLimit(2)
                                    .frame(width: g.size.width, height: g.size.height)
                                    .minimumScaleFactor(0.5)
                                    .background(
                                        Rectangle()
                                            .fill((item == selectedItem) ? Color(.green) : .white)
                                            .frame(width: g.size.width, height: g.size.height)
                                            .border(Color.gray)
                                    ).scaledToFit()
                            }
                            .frame(width: geom.size.width*0.92, height: 45)
                        })
                      .disabled((Int(QuestionManager.answers.year) == Calendar.current.component(.year, from: Date())) ? validateMonth(item: item) : false)
                    }
                }
                .frame(width: geom.size.width)
            }
        }
    }
    
    func validateMonth(item: MyItem) -> Bool {
        if let itemOffset = listItems.firstIndex(where: {$0.id == item.id}) {
            // ... do your validation
            return true
        }
        return false
    }
   
}
于 2021-11-21T01:05:04.030 回答