Last active
July 17, 2023 17:48
-
-
Save lightandshadow68/ba7c53ca446e62bd4602635a70cde37b to your computer and use it in GitHub Desktop.
Vanilla SwiftUI Core Data edit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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