- Görkem Güray/
- SwiftUI in 100 Days Notes/
- Day 56 - SwiftUI Project-11 (BookWorm) Challange and Solutions/
Day 56 - SwiftUI Project-11 (BookWorm) Challange and Solutions
Table of Contents
Congratulations on finishing another SwiftUI project! With technologies like SwiftData on your side, you can now build some serious apps that interact with the user and most importantly remember what they input. While we’ve only had one introduction to SwiftData, it can do so much more, and I expect Apple to continue to expand the connection between SwiftData and SwiftUI in future updates. In the meantime, the next project focuses on SwiftData in depth.
Challange #
- Currently it is possible to leave title, author and genre unset when saving a book, which causes a problem for detail view. Please fix this by forcing defaults, validating the form or showing a default image for unknown genres, the choice is yours.
- Modify the ContentView so that books rated 1 star are highlighted in some way, for example by showing their name in red.
- Add a new “date” attribute to the Book class, assign
Date.now
to get the current date and time, then format it nicely somewhere in theDetailView
.
Solutions #
-
The way I have chosen to solve this step is that if the fields consist of whitespaces, we will not allow to press the save button. For this we will write a String extension in AddBookView and check if the String consists of whitespaces. Add the following code for this;
extension String { var isBlank: Bool { allSatisfy({$0.isWhitespace}) } }
Then we will add a computed variable and check that all fields meet our conditions.
var isAllAreaValid: Bool { if title.isBlank || author.isBlank || rating<1 || review.isBlank { return false } return true }
Finally, change Section-3 in AddBookView Form as follows;
Section { Button("Save") { let newBook = Book(title: title, author: author, genre: genre, review: review, rating: rating) modelContext.insert(newBook) dismiss() } //Button .disabled(isAllAreaValid == false) } //Section-3
-
To solve this problem, we will add the following modifier to the Text view in the ContentView where we write the name of the book. In this way, if 1 star is given, the book name will be in red colour, otherwise we will leave it in default colour.
Text(book.title) .font(.headline) .foregroundStyle(book.rating == 1 ? .red : .primary)
-
To solve this problem, let’s first add a new attribute to the Book class and give its default value;
var date = Date.now
Then let’s add to the init method of the Book class as follows;
init(title: String, author: String, genre: String, review: String, rating: Int, date: Date) {
After doing these operations, since we want to get the time when the save button is pressed in AddBookView, let’s change the
let newBook
part as follows;let newBook = Book(title: title, author: author, genre: genre, review: review, rating: rating, date: Date.now)
Finally, in DetailView, we want to show the date on the image as follows
For this, let’s change the ZStack section as follows;
ZStack(alignment: .bottom) { Image(book.genre) .resizable() .scaledToFit() HStack() { Text(book.date, format: .dateTime) .font(.caption) .fontWeight(.black) .padding(8) .foregroundStyle(.white) .background(.black.opacity(0.75)) .clipShape(.capsule) .offset(x: +5, y: -5) Spacer() Text(book.genre.uppercased()) .font(.caption) .fontWeight(.black) .padding(8) .foregroundStyle(.white) .background(.black.opacity(0.75)) .clipShape(.capsule) .offset(x: -5, y: -5) } } //ZStack
Also, let’s make a small change in the code so that the preview code in DetailView is not broken;
let example = Book(title: "Test Book", author: "Test Author", genre: "Fantasy", review: "This was a great book; I really enjoyed it.", rating: 4, date: Date.now)
You can also read this article in Turkish.
Bu yazıyı Türkçe olarak da okuyabilirsiniz.