SwiftUI @FocusState 在键盘首次出现时重新渲染视图

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

我有“NewEditListView”,它允许您创建一个新的“ListItem”(SwiftDate 对象)或编辑它,我的问题是当我显示键盘(仅第一次)编辑“ListItem”名称时,它会导致重新渲染视图,并第二次在视图模型中调用“ListItemManager.configureList(for: id, context)”方法,并使用给定的“id”创建新的“ListItem”或将编辑的“ListItem”传递给新的模型上下文,如何避免这个问题? 我不知道这是否有任何效果,但我使用表格呈现视图。

视图模型:

extension NewEditListView {
    
    @Observable
    final class ViewModel {
        
        // MARK: - Properties
        var list: ListItem
               
        // MARK: - Init
        init(id: PersistentIdentifier?, _ container: ModelContainer) {
            let context = ModelContext(container)
            self.list = ListItemManager.configureList(for: id, context)
        }       
    }
}

景色:

struct NewEditListView: View {
    
    // MARK: - Properties
    let id: PersistentIdentifier?
    @State private var viewModel: ViewModel
    @FocusState private var isFocused: Bool
    @Environment(\.dismiss) private var dismiss
    
    init(id: PersistentIdentifier?, container: ModelContainer) {
        self.id = id
        let viewModel = ViewModel(id: id, container)
        _viewModel = State(initialValue: viewModel)
    }
    
    // MARK: - Body
    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: 24) {
                    textField
                }
                .padding(.top, 24)
            }
            .navigationTitle(viewModel.initialListItem.isNew ? "New List" : "Edit List")
            .navigationBarTitleDisplayMode(.inline)
            .background(Color(.systemGroupedBackground))
            .interactiveDismissDisabled(true)
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now()+1) {
                    isFocused = true
                }
            }
        }
    }
    
    // MARK: - Views 
    private var textField: some View {
        TextField("List name", text: $viewModel.list.name)
            .font(.title3)
            .fontWeight(.semibold)
            .submitLabel(.done)
            .padding(.leading, 16)
            .frame(maxWidth: .infinity)
            .frame(height: 48)
            .padding(.horizontal, 16)
            .focused($isFocused)
    }
}

提出观点:

        .sheet(isPresented: $presentingSheet, content: {
            NewEditListView(id: nil, container: context.container)
        })
swiftui keyboard swift-data
1个回答
0
投票

要解决此问题,我们需要:

  1. 在“NewEditListView”中创建列表“@Bindable var list: ListItem”
  2. 我们传递给“NewEditListView”的列表需要是“@State var list: ListItem”
© www.soinside.com 2019 - 2024. All rights reserved.