显示带有来自Core Data的布尔值的.sheet

时间:2019-12-14 13:34:20

标签: swiftui

我有一个工作表,其中显示了我的应用程序的指南。 该工作表由当地的bool展示(Guide)提供。 我希望该本地布尔对象通过bool showGuide来在我的设置实体中镜像Core Data中的布尔对象

我知道一般如何保存和检索布尔状态,但是在应用启动时从核心数据中检索布尔是我遇到的问题。

当用户点击“知道了!”按钮时我希望该指南不再显示。 (也许我可能会在设置视图中设置一个按钮,如果需要刷新,可以再次激活它)

我尝试使用“测试”视图的自定义初始化程序来尝试检索settings.showGuide,但是没有运气。

我也了解设置是一个数组,因此我必须始终保存并检索到settings数组中的第一项。有没有更简单的方法可以做到这一点?保存一个实体而不是数组?

有什么想法吗?

import Foundation
import SwiftUI
import CoreData


struct Test: View {

    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(fetchRequest: Settings.getSettings()) var settings:FetchedResults<Settings>

    @State private var showingGuide = true

    var body: some View{

        VStack{
            Text("Hello")
        }
        .sheet(isPresented: $showingGuide) {

            MainGuide().padding(.horizontal)

            Button(action: {
                let settings = Settings(context: self.managedObjectContext)
                settings.showGuide = false
                self.showingGuide = false
                do {
                    try self.managedObjectContext.save()
                }catch{
                    print(error)
                }
            }){
                Text("Got it!")

            }.padding()
        }
    }


}

enter image description here

CoreData

1 个答案:

答案 0 :(得分:0)

您不应该以编程方式设置@State变量(link)。而是使用if对象中的布尔值的CoreData语句显示或不显示工作表。

我还建议为设置对象添加一个计算变量,因为它始终是数组中的第一个元素,如以下var settings的代码所示。

您可以这样做:

struct ContentView: View {

    @Environment(\.managedObjectContext) var managedObjectContext

    @FetchRequest(
        entity: Settings.entity(),
        sortDescriptors: [
            NSSortDescriptor(keyPath: \Settings.self, ascending: false)
        ]
    ) var settingsRequest: FetchedResults<Settings>

    var settings:Settings{
        settingsRequest[0]
    }

    @State var showGuide:Bool = true

    var body: some View{
        VStack{
            if settings.showSheet{
                Text("show sheet: \(String(settings.showSheet))").sheet(isPresented: $showGuide){
                    Text("Hello from Sheet")
                    Button(action: {
                        self.settings.showSheet = false
                        self.showGuide = false
                        do {
                            try self.managedObjectContext.save()
                        }catch{
                            print(error)
                        }
                    }){
                        Text("Got it!")

                    }.padding()
                }
            }else{
                Text("already agreed")
            }
        }
    }
}

注意:仅当用户单击按钮时,这才会将settings.showSheet设置为true。通过滑动消除工作表时,它不会更新CoreData。如果要对滑动操作执行某些操作,可以使用.onDismiss(perform: { })