许多文本字段的性能问题

问题描述 投票:0回答:1

我需要有许多文本字段来处理表单之类的内容。总是有类似键文本字段和值文本字段之类的东西。所以我想使用具有两列的 LazyVGrid。 此时每个文本字段都使用自定义绑定,这就是文本字段:

struct FocusField: View {
    
    @State var index: Int
    @Binding var focus: String?
    @Binding var content: [String]
    
    @FocusState var isFocused: String?
    var nextFocus: () -> Void
    
    @ObservedObject var player = Player.shared
    
    var body: some View {
        if index < content.endIndex {
            HStack{
                TextField(((index % 2 == 0) ? player.language1 : player.language2),
                          text:
                            Binding<String>(
                                get: {
                                    if content.endIndex > index {
                                        return content[index]
                                    }
                                    return ""
                                    
                                }, set: {newValue in
                                    if content.endIndex > index {
                                        content[index] = newValue
                                    }
                                }
                            )
                          //                          ,
                          //                          axis: .vertical
                )
                
#if os(iOS)
                .autocapitalization(UITextAutocapitalizationType.none)
#endif
                .multilineTextAlignment(.leading)
                .onSubmit {
                    self.nextFocus()
                }
                .onChange(of: focus, perform: { newValue in
                    self.isFocused = newValue
                })
                .focused(self.$isFocused, equals: "\(content[index])\(index)")
                if isFocused == "\(content[index])\(index)"{
                    if index % 2 != 0{
                        Button(role: .destructive) {
                            if content.count > 2 {
                                content.remove(at: index)
                                content.remove(at: index)
                            } else {
                                content = ["",""]
                            }
                        } label: {
                            Image(systemName: "trash.fill")
                        }
                    }
                }
                
            }
        }
    }
}

这是我如何使用它们。在具有两列的 LazyVGrid 内部:

struct EditViewInDetailView: View{
    @Binding var item: Item?
    @ObservedObject var viewModel = VocabDetailViewModel.shared
    @State var focus: String? = nil
    @Binding var isExpanded : PresentationDetent
    
    let columns : [GridItem] = Array(repeating: .init(.flexible()), count: 2)
    var body: some View{
        ScrollViewReader{scroll in
            ScrollView{
                LazyVGrid(columns: columns) {
                    ForEach(0..<(viewModel.content.count), id: \.self) { index in
                        LazyVStack{
                            Spacer()
                            FocusField(index: index, focus: $focus, content: $viewModel.content) {
                                if index % 2 != 0 {
                                    viewModel.content.insert("", at: (index % 2 == 0 ? (index+2) : (index + 1))  )
                                    viewModel.content.insert("", at: (index % 2 == 0 ? (index+2) : (index + 1))  )
                                }
                                DispatchQueue.main.asyncAfter(deadline: .now() + (0.01 * Double(index)) ) {
                                    focus = "\(viewModel.content[index+1])\(index+1)"
                                }
                            }
                            Spacer()
                            Divider()
                                .padding(.horizontal, -10)
                                .background(.gray)
                        }
                    }
                    
                    
                }
                
                Button("Zurück"){
                    isExpanded = .height(81)
                }
                .buttonStyle(BorderedProminentButtonStyle())
                Spacer()
                    .frame(height: 100)
            }
        }
    }
}

如果有很多文本字段,滚动性能会大幅下降,并且无法在索引较高的字段中输入内容。当您点击文本字段时,键盘会立即显示并退出。

我尝试使用文本代替,并在聚焦时将文本更改为文本字段,但它没有更改为文本字段。

有人知道代码的哪一部分使它如此慢吗?

ios swiftui data-binding lazyvgrid
1个回答
0
投票

我认为你应该使用一个迭代键值对的列表。那么您不需要检查索引 % 2 并且不需要自定义绑定。对于删除,您可以使用 .onDelete 修饰符而不是自定义删除按钮。由于代码更简单,您可以直接在包含列表的视图中使用 focusstate。所以你不需要 isFocused 属性。而且它看起来应该好多了;-).

© www.soinside.com 2019 - 2024. All rights reserved.