I am currently building a new app where I needed to show ratings for items. Ratings are from 0 to 5 with 0.5 step. In this blog post, we’ll implement a SwiftUI view which uses SF symbols to display ratings. Since we need to make sure it works properly with each of the step, we are going to leverage the usefulness of SwiftUI previews and render each state one by one vertically. Swift has a function called stride what we can use to easily create an array of double values with a step of 0.5 and feed it in to ForEach.
The view needs to render 5 stars next to each other and figure out which stars are filled, half filled or empty. Rendering 5 images is straight-forward in SwiftUI. We can use HStack and ForEach with an integer range from 0 to 5. Since we use SF symbols, then the colour of the filled star can be applied with the foregroundColor view modifier.
The most complicated part is implementing a function what returns the name of the SF symbol for the current star index and the double value passed into the view. When I thought about it then I ended up with two solutions: one with if clauses and the other one with switch statement.
The solution A is checking if the value is larger than the star index + 1 which means that in case of value 1.0 the zero indexed star image is rendered as filled star. Half-filled cases are handled by checking if the zero indexed star index + 0.5 is less than the current value. The solution B uses open-ended ranges and a switch statement. When we subtract the zero indexed star index from the current value, then if it is less than 0.5 then the star should be not filled, if 0.5 to 1.0 then half-filled and in other cases filled. When comparing these implementations, then the B is more concise, but on the other hand A is more readable. Years ago I read a book “Masters of Doom” and John Romero’s programming principles. Don’t know why, but his programming principle “simplify” always pops on my mind when I need to decide on multiple implementations. Like here, only because of this, I am going for solution A.
If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading.