Core Dataで本を作成する
Creating books with Core Data
最初のタスクは、本のコアデータモデルを設計し、次にデータベースに本を追加するための新しいビューを作成することです。
Bookworm.xcdatamodeld追加作業にて、
新たに、Book追加した段階でerror有り。
一旦、削除し新たに作成してOKとなる。
import SwiftUI struct AddBookView: View { @Environment(\.managedObjectContext) var moc @State private var title = "" @State private var author = "" @State private var rating = 3 @State private var genre = "" @State private var review = "" let genres = ["Fantasy", "Horror", "Kids", "Mystery", "Poetry", "Romance", "Thriller"] @Environment(\.presentationMode) var presentationMode var body: some View { NavigationView { Form { Section { TextField("Name of book", text: $title) TextField("Author's name", text: $author) Picker("Genre", selection: $genre) { ForEach(genres, id: \.self) { Text($0) } } } Section { Picker("Rating", selection: $rating) { ForEach(0..<6) { Text("\($0)") } } TextField("Write a review", text: $review) } Section { Button("Save") { // add the book let newBook = Book(context: self.moc) newBook.title = self.title newBook.author = self.author newBook.rating = Int16(self.rating) newBook.genre = self.genre newBook.review = self.review try? self.moc.save() self.presentationMode.wrappedValue.dismiss() } } } .navigationBarTitle("Add Book") } } } struct AddBookView_Previews: PreviewProvider { static var previews: some View { let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext return AddBookView().environment(\.managedObjectContext, context) } }
import SwiftUI import CoreData struct ContentView: View { @Environment(\.managedObjectContext) var moc @FetchRequest(entity: Book.entity(), sortDescriptors: []) var books: FetchedResults<Book> @State private var showingAddScreen = false var body: some View { NavigationView { Text("Count: \(books.count)") .navigationBarTitle("Bookworm") .navigationBarItems(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) } }
カスタムの星評価コンポーネントの追加
Adding a custom star rating component
import SwiftUI struct RatingView: View { @Binding var rating: Int var label = "" var maximumRating = 5 var offImage: Image? var onImage = Image(systemName: "star.fill") var offColor = Color.gray var onColor = Color.yellow func image(for number: Int) -> Image { if number > rating { return offImage ?? onImage } else { return onImage } } var body: some View { HStack { if label.isEmpty == false { Text(label) } ForEach(1..<maximumRating + 1) { number in self.image(for: number) .foregroundColor(number > self.rating ? self.offColor : self.onColor) .onTapGesture { self.rating = number } } } } } struct RatingView_Previews: PreviewProvider { static var previews: some View { RatingView(rating: .constant(4)) } }
@FetchRequestでリストを作成する
Building a list with @FetchRequest
SwiftUIを使用すると、カスタムUIコンポーネントを簡単に作成できます。これは、これらのコンポーネントが実質的には@Binding、私たちが読むために公開された一種のビューにすぎないためです。
これを実証するために、ユーザーが画像をタップして1から5までのスコアを入力できる星評価ビューを作成します。
import SwiftUI struct EmojiRatingView: View { let rating: Int16 var body: some View { switch rating { case 1: return Text("1") case 2: return Text("2") case 3: return Text("3") case 4: return Text("4") default: return Text("5") } } } struct EmojiRatingView_Previews: PreviewProvider { static var previews: some View { EmojiRatingView(rating: 3) } }
import SwiftUI import CoreData struct ContentView: View { @Environment(\.managedObjectContext) var moc @FetchRequest(entity: Book.entity(), sortDescriptors: []) var books: FetchedResults<Book> @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")) { EmojiRatingView(rating: book.rating) .font(.largeTitle) VStack(alignment: .leading) { Text(book.title ?? "Unknown Title") .font(.headline) Text(book.author ?? "Unknown Author") .foregroundColor(.secondary) } } } } .navigationBarTitle("Bookworm") .navigationBarItems(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) }書籍の詳細を表示しています }