Your Second iOS & SwiftUI App

Nov 4 2021 · Swift 5.5, iOS 15, Xcode 13

Part 2: Data Flow

18. Challenge: Micro-Review

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 17. Observable Objects Next episode: 19. Conclusion

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 18. Challenge: Micro-Review

In the previous episode, you were able to get one of two new book properties displaying in your UI: the “read me” bookmark.

Now, your challenge is to handle the other one: the micro-review. A book row should display a review, if one exists. And you should be able to edit the review, from the detail view.

You’ll need to make use of a TextField view for that. Its initializer’s second argument will need to be bound, somehow, to a book’s review. Pause the video, and good luck with finishing up this part of the course!

For this challenge, I actually decided to start working in DetailView, instead of ContentView. They both needed work, so you could go either way.

Right above the Book Image, I created a Text Field, with “Review” as the default that would show when nothing had been entered.

      VStack {
        TextField("Review…", text: <#T##Binding<String>#>)

        Book.Image(

That needed a binding to a String. Luckily an ObservedObject variable can give that to me, just like a State variable can.

TextField("Review…", text: $book.microReview)

And I made that a little easier on the eyes, by surrounding it with dividers that used vertical padding.

      VStack {
        Divider()
          .padding(.vertical)
        TextField("Review…", text: $book.microReview)
        Divider()
          .padding(.vertical)

        Book.Image(

With that screen taken care of, I moved over to BookRow.

I wanted the micro-review …right underneath the title and author stack.

        )
        
        VStack {
          TitleAndAuthorStack(
            book: book,
            titleFont: .title2,
            authorFont: .title3
          )
          .lineLimit(1)

          Text(book.microReview)
        }

        Spacer()

I moved that lineLimit to the VStack, so it would apply to the microReview, too.

            authorFont: .title3
          )

          Text(book.microReview)
        }
        .lineLimit(1)

        Spacer()

Now, at that moment, there was no review data. So I provided myself some, in the Library.

It didn’t really matter what I wrote, or for which books. I just made sure I had a mix of books with, and without, microReviews.

    .init(title: "Bosch", author: "Laurinda Dixon"🟩, microReview: "Earthily Delightful."),
    .init(title: "Dare to Lead", author: "Brené Brown"),
    .init(title: "Blasting for Optimum Health Recipe Book", author: "NutriBullet"),
    .init(title: "Drinking with the Saints", author: "Michael P. Foley"🟩, microReview: "One of Ozma's favorites 😻"),
    .init(title: "A Guide to Tea", author: "Adagio Teas"),
    .init(title: "The Life and Complete Work of Francisco Goya", author: "P. Gassier & J Wilson"🟩, microReview: "Book too large for a micro review!"),

Having a look at my list again…

…there were the reviews.

I just control-option-clicked on this VStack and set its alignment to leading, so they’d look mode orderly. And I gave them a little style: the subheadline font…

            Text(book.microReview)
              .font(.subheadline)
          }

…and the “secondary” foreground color.

              .font(.subheadline)
              .foregroundColor(.secondary)
          }

I thought a Spacer() would be nice, too.

            authorFont: .title3
          )

          Spacer()
          Text(book.microReview)
        }

…But not always. I had two bad-looking empty views, for the rows without reviews. So I only showed them when the review wasn’t empty.

            authorFont: .title3
          )

          if !book.microReview.isEmpty {
            Spacer()
            Text(book.microReview)
          }
        }
        .lineLimit(1)

Then, all the row text was vertically centered. Could I have edited the review, at that point?

Well, that didn’t show up in the book row…

But the review did get stored. Which is reminiscent of our situation from the previous episode. And the fix was the same.

@ObservedObject var book: Book

The BookRow had to observe changes to its book property, and that property had to be a variable.

And with that, I had dynamically-editable reviews!