Skip to content

Instantly share code, notes, and snippets.

@lightandshadow68
Last active July 17, 2023 17:48
Show Gist options
  • Save lightandshadow68/ba7c53ca446e62bd4602635a70cde37b to your computer and use it in GitHub Desktop.
Save lightandshadow68/ba7c53ca446e62bd4602635a70cde37b to your computer and use it in GitHub Desktop.
Vanilla SwiftUI Core Data edit
import SwiftUI
import CoreData
struct PostEditView: View {
@ObservedObject var post: Post
@Environment(\.managedObjectContext) var moc
@State var hasChanges: Bool = false
var body: some View {
Form {
TextField("Title", text: $post.title.optionalBinding)
TextEditor(text: $post.content.optionalBinding)
.frame(height: 120.0)
TextField("Excerpt", text: $post.excerpt.optionalBinding)
HStack {
Toggle(isOn: $post.publishedAt.optionalBinding(falseValue: nil)) {
HStack {
Text("Published")
if let at = post.publishedAt {
Spacer()
Text(at,format: Date.FormatStyle.dateTime)
.foregroundStyle(.secondary)
}
}
}
}
if let createdAt = post.createdAt {
LabeledContent("Created") {
Text(createdAt,format: Date.FormatStyle.dateTime)
}
}
}
.toolbar {
ToolbarItemGroup(placement: .confirmationAction) {
Button {
updatePost()
} label: {
Text(post.createdAt != nil ? "Update" : "Save")
}
.disabled(!hasChanges)
}
}
.onChange(of: post.hasPersistentChangedValues ) { newValue in
updateHasChanges()
}
.onAppear() {
updateHasChanges()
}
}
func updateHasChanges() {
hasChanges = post.hasPersistentChangedValues
}
func updatePost() {
do {
try moc.save()
updateHasChanges()
} catch {
print(">>>>> Error saving Post")
}
}
}
struct PostEditView_Previews: PreviewProvider {
@Environment(\.managedObjectContext) var moc
static var previews: some View {
NavigationView {
PostEditView(post: Post(context: PersistenceController.preview.container.viewContext))
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
}
// String? <-> String
extension Binding where Value == String? {
var optionalBinding: Binding<String> {
.init(
get: {
self.wrappedValue ?? ""
}, set: {
self.wrappedValue = $0.isEmpty ? nil : $0
}
)
}
}
// Date? <-> String
extension Binding where Value == Date? {
func optionalBinding(formatter: DateFormatter) -> Binding<String> {
.init(
get: {
self.wrappedValue != nil ? formatter.string(from: self.wrappedValue!) : ""
}, set: {
self.wrappedValue = $0.isEmpty ? nil : formatter.date(from: $0)
}
)
}
}
// PublishedAt? <-> Bool
extension Binding where Value == Date? {
func optionalBinding(falseValue: Date? = nil) -> Binding<Bool> {
.init(
get: {
return self.wrappedValue != nil
}, set: { _ in
self.wrappedValue = self.wrappedValue == nil ? .now : falseValue
}
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment