gpt4 book ai didi

表单修饰符的 SwiftUI 问题

转载 作者:行者123 更新时间:2023-12-03 14:00:59 28 4
gpt4 key购买 nike

我的应用中有一个初始 View ,需要打开一些模态视图。我正在使用的数据是核心数据,我正在使用 @FetchedRequest 填充 ListView 属性包装器。我尝试制作的 UI 类似于您在 iOS 13 的提醒应用中创建和编辑列表的方式。

  • 添加记录 - 允许用户随时创建新列表(子对象稍后)。
  • 编辑记录 - 将 ListView 切换到编辑模式,点击一行上的编辑按钮以打开模式以编辑记录。

  • 这两种方法现在都可以正常工作,但存在一些问题。
  • 当我关闭“添加”模式时,有时我无法点击 View 右上角的“编辑”按钮。点击时什么都不会发生。我尝试附加打印状态语句并且没有被调用。大多数情况下都会发生这种情况,但并非总是如此。
  • 当我使用上述过程编辑记录时,当点击取消或完成关闭此模式时,它将关闭。但在此之后,我无法使用此功能。如果我尝试打开另一个编辑模型,它会打开,但我传递给它的数据永远不会显示在字段中。

  • 我将它们分成两个 View 和工作表,因为当我将它们组合成一个 View 和工作表时遇到了很多问题。

    更新:根据 this,通过将两个 .sheet 修饰符移到 NavigationView 之外并将它们附加到一些隐藏对象来解决问题 1。回答。

    至于问题 2,我今晚花了一些时间尝试了一些不同的事情,我想我可以看到问题所在。在初次使用后重新打开编辑模式时,它正在经历任何类型的初始化过程。没有调用初始化,甚至 onAppear()未调用附加到 View 。在这种情况下,文本字段使用的@State 变量永远不会用记录中的值填充,因为不会再次调用文本字段代码。我不知道如何处理这个问题。在任何其他环境中,我只会删除实例并创建一个新实例,但我不知道如何删除模式创建的编辑 View 的缓存实例。

    更新:自 2019.08.27 起,iOS 13.1 修复了第二个问题。我什至不必重新编译即可看到修复。

    列表显示

    更新为将工作表移到 NavigationView 之外
    import SwiftUI

    struct TimelineListView: View {

    @Environment(\.managedObjectContext) var managedObjectContext

    @FetchRequest(fetchRequest: Timeline.allTimelinesFetchRequest()) var timelines: FetchedResults<Timeline>

    @State var listViewEditMode: EditMode = .inactive

    @State var openModalSheetAdd = false

    @State var openModalSheetEdit = false
    @State var timelineToEdit: Timeline?

    var body: some View {
    VStack{
    NavigationView {
    VStack {

    List(self.timelines) { timeline in

    NavigationLink(destination: TimelineDetailView(timeline: timeline)) {

    HStack{
    Text(timeline.name ?? "Unnamed List")
    if (self.listViewEditMode == .active) {
    Spacer()
    Image(systemName: "info.circle")
    .onTapGesture {
    self.timelineToEdit = timeline
    self.listViewEditMode = .inactive
    self.openModalSheetEdit = true
    }
    }
    }

    } // End Navigation Link

    } // End List

    HStack {
    Spacer()
    Button("Add List") {
    self.openModalSheetAdd = true
    }.padding(EdgeInsets(top: 0, leading: 0, bottom: 10, trailing: 20))
    }
    }

    .navigationBarTitle(Text("Lists"), displayMode: .inline)
    .navigationBarItems(trailing: EditButton())

    .environment(\.editMode, self.$listViewEditMode)

    }// End Navigation View

    // Edit modal
    Text("").hidden()
    .sheet(isPresented: $openModalSheetEdit,
    onDismiss: {
    self.openModalSheetEdit = false
    },
    content: {
    TimelineEditView(timeline: self.timelineToEdit, onDismiss: {
    self.openModalSheetEdit = false // this is here because sometimes onDismiss is not called.
    })
    .environment(\.managedObjectContext, self.managedObjectContext)
    })

    // Add modal
    Text("").hidden()
    .sheet(isPresented: $openModalSheetAdd,
    onDismiss: {
    self.openModalSheetAdd = false
    },
    content: {
    TimelineAddView(onDismiss: {
    self.openModalSheetAdd = false // this is here because sometimes onDismiss is not called.
    })
    .environment(\.managedObjectContext, self.managedObjectContext)
    })
    }

    }
    }

    添加记录 View
    struct TimelineAddView: View {

    @Environment(\.managedObjectContext) var managedObjectContext
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    @State private var nameEdit: String = ""


    // This closure is here to call when we dismiss the modal because onDismiss is not always called
    var onDismiss: () -> ()

    var body: some View {

    VStack {
    HStack {

    Button(action: ({
    self.nameEdit = ""
    self.presentationMode.wrappedValue.dismiss()
    self.onDismiss()
    })) {
    Text("Cancel")
    }
    .padding(EdgeInsets(top: 10, leading: 10, bottom: 0, trailing: 0))

    Spacer()

    Button(action: ({
    let newTimeline = Timeline(context: self.managedObjectContext)
    newTimeline.name = self.nameEdit
    self.nameEdit = ""
    do {
    try self.managedObjectContext.save()
    } catch {
    print(error)
    }
    self.presentationMode.wrappedValue.dismiss()
    self.onDismiss()
    })) {
    Text("Done")
    }
    .padding(EdgeInsets(top: 10, leading: 0, bottom: 0, trailing: 10))
    }

    TextField("Data to edit", text: self.$nameEdit)
    .shadow(color: .secondary, radius: 1, x: 0, y: 0)
    .textFieldStyle(RoundedBorderTextFieldStyle())
    .onAppear {
    self.nameEdit = ""
    }.padding()
    Spacer()
    }
    }
    }

    编辑记录 View
    struct TimelineEditView: View {

    @Environment(\.managedObjectContext) var managedObjectContext
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    @State private var nameEdit = ""
    var timeline : Timeline?

    // This closure is here to call when we dismiss the modal because onDismiss is not always called
    var onDismiss: () -> ()

    var body: some View {

    return VStack {
    HStack {
    Button(action: ({
    // Dismiss the modal sheet
    self.nameEdit = ""
    self.presentationMode.wrappedValue.dismiss()
    self.onDismiss()
    })) {
    Text("Cancel")
    }
    .padding(EdgeInsets(top: 10, leading: 10, bottom: 0, trailing: 0))

    Spacer()
    Button(action: ({

    self.timeline?.name = self.nameEdit

    do {
    try self.managedObjectContext.save()
    } catch {
    print(error)
    }

    // Dismiss the modal sheet
    self.nameEdit = ""
    self.presentationMode.wrappedValue.dismiss()
    self.onDismiss()
    })) {
    Text("Done")
    }
    .padding(EdgeInsets(top: 10, leading: 0, bottom: 0, trailing: 10))
    }

    TextField("Data to edit", text: self.$nameEdit)
    .shadow(color: .secondary, radius: 1, x: 0, y: 0)
    .textFieldStyle(RoundedBorderTextFieldStyle())
    .onAppear {
    self.nameEdit = self.timeline?.name ?? ""
    }.padding()
    Spacer()
    }
    }
    }

    最佳答案

    .sheet嵌入到 List 中只打开一次是一个已知的错误,我希望他们修复它。在那之前你必须搬家.sheet在任何 List 之外.

    但自从 .sheet不在 List 内但在 NavigationView 内, 尝试移动 .sheet 可能是个好主意在它之外。

    但是不要附两个.sheet两个相同的 View ,但按以下方式添加它们:

    VStack{
    NavigationView{ ... }
    Text("").hidden().sheet(...)
    Text("").hidden().sheet(...)
    }

    关于表单修饰符的 SwiftUI 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57631666/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com