書籍の詳細を表示しています
Showing book details
import SwiftUI import CoreData struct DetailView: View { let book: Book var body: some View { GeometryReader { geometry in VStack { ZStack(alignment: .bottomTrailing) { Image(self.book.genre ?? "Fantasy") .frame(maxWidth: geometry.size.width) Text(self.book.genre?.uppercased() ?? "FANTASY") .font(.caption) .fontWeight(.black) .padding(8) .foregroundColor(.white) .background(Color.black.opacity(0.75)) .clipShape(Capsule()) .offset(x: -5, y: -5) } Text(self.book.author ?? "Unknown author") .font(.title) .foregroundColor(.secondary) Text(self.book.review ?? "No review") .padding() RatingView(rating: .constant(Int(self.book.rating))) .font(.largeTitle) Spacer() } } .navigationBarTitle(Text(book.title ?? "Unknown Book"), displayMode: .inline) } } struct DetailView_Previews: PreviewProvider { static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) static var previews: some View { let book = Book(context: moc) book.title = "Test book" book.author = "Test author" book.genre = "Fantasy" book.rating = 4 book.review = "This was a great book; I really enjoyed it." return NavigationView { DetailView(book: book) } } }
NSSortDescriptorによるフェッチ要求のソート
Sorting fetch requests with NSSortDescriptor
struct ContentView: View { @Environment(\.managedObjectContext) var moc //@FetchRequest(entity: Book.entity(), sortDescriptors: []) var books: FetchedResults<Book> //@FetchRequest(entity: Book.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Book.title, ascending: true)]) var books: FetchedResults<Book> @FetchRequest(entity: Book.entity(), sortDescriptors: [ NSSortDescriptor(keyPath: \Book.title, ascending: true), NSSortDescriptor(keyPath: \Book.author, ascending: true) ]) var books: FetchedResults<Book> @State private var showingAddScreen = false var body: some View {
コアデータフェッチリクエストからの削除
Deleting from a Core Data fetch request
import SwiftUI import CoreData struct ContentView: View { @Environment(\.managedObjectContext) var moc //@FetchRequest(entity: Book.entity(), sortDescriptors: []) var books: FetchedResults//@FetchRequest(entity: Book.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Book.title, ascending: true)]) var books: FetchedResults @FetchRequest(entity: Book.entity(), sortDescriptors: [ NSSortDescriptor(keyPath: \Book.title, ascending: true), NSSortDescriptor(keyPath: \Book.author, ascending: true) ]) var books: FetchedResults //--------------------------------- func deleteBooks(at offsets: IndexSet) { for offset in offsets { // find this book in our fetch request let book = books[offset] // delete it from the context moc.delete(book) } // save the context try? moc.save() } @State private var showingAddScreen = false var body: some View { NavigationView { //Text("Count: \(books.count)") List { ForEach(books, id: \.self) { book in //NavigationLink(destination: Text(book.title ?? "Unknown Title")) { NavigationLink(destination: DetailView(book: book)) { EmojiRatingView(rating: book.rating) .font(.largeTitle) VStack(alignment: .leading) { Text(book.title ?? "Unknown Title") .font(.headline) Text(book.author ?? "Unknown Author") .foregroundColor(.secondary) } } }.onDelete(perform: deleteBooks) } .navigationBarTitle("Bookworm") //.navigationBarItems(trailing: Button(action: { .navigationBarItems(leading: EditButton(), trailing: Button(action: { self.showingAddScreen.toggle() }) { Image(systemName: "plus") }) .sheet(isPresented: $showingAddScreen) { AddBookView().environment(\.managedObjectContext, self.moc) } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext return ContentView().environment(\.managedObjectContext, context) } }
アラートを使用してプログラムでNavigationLinkをポップする
Using an alert to pop a NavigationLink programmatically
import SwiftUI import CoreData struct DetailView: View { let book: Book @Environment(\.managedObjectContext) var moc @Environment(\.presentationMode) var presentationMode @State private var showingDeleteAlert = false func deleteBook() { moc.delete(book) // uncomment this line if you want to make the deletion permanent // try? self.moc.save() presentationMode.wrappedValue.dismiss() } var body: some View { GeometryReader { geometry in VStack { ZStack(alignment: .bottomTrailing) { Image(self.book.genre ?? "Fantasy") .frame(maxWidth: geometry.size.width) Text(self.book.genre?.uppercased() ?? "FANTASY") .font(.caption) .fontWeight(.black) .padding(8) .foregroundColor(.white) .background(Color.black.opacity(0.75)) .clipShape(Capsule()) .offset(x: -5, y: -5) } Text(self.book.author ?? "Unknown author") .font(.title) .foregroundColor(.secondary) Text(self.book.review ?? "No review") .padding() RatingView(rating: .constant(Int(self.book.rating))) .font(.largeTitle) Spacer() } } .navigationBarTitle(Text(book.title ?? "Unknown Book"), displayMode: .inline) .alert(isPresented: $showingDeleteAlert) { Alert(title: Text("Delete book"), message: Text("Are you sure?"), primaryButton: .destructive(Text("Delete")) { self.deleteBook() }, secondaryButton: .cancel() ) } .navigationBarItems(trailing: Button(action: { self.showingDeleteAlert = true }) { Image(systemName: "trash") }) } } struct DetailView_Previews: PreviewProvider { static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) static var previews: some View { let book = Book(context: moc) book.title = "Test book" book.author = "Test author" book.genre = "Fantasy" book.rating = 4 book.review = "This was a great book; I really enjoyed it." return NavigationView { DetailView(book: book) } } }