Recently I had a need to show the simple rating control in one of our iOS apps - the typical row of stars, few leftmost highlighted, the more highlighted, the better the rating is - something as obvious as this:
My first thoughts were wandering around star images one after another, the hell with positioning with frames or multitude of Auto Layout constraints. Nah. The second take led me to
EDStarRating, a library that does this pretty well. But all I needed was only to show few stars in a row, all the events handling and customizations seemed a bit overkill for the simple task I was facing.
Then the aha! moment came. I can just play with
NSAttributedString, a fancy thing that adds a lot of formatting capabilities to ordinary string or even parts of it. And there is the awesome set of icons everyone’s using anyway in Font Awesome. So here are the steps I ended up doing:
There are multiple ways how to do that. We decided to add
FontAwesome.otf definition file as a resource to our project, because all I need is just to be able do the following:
You might prefer to choose one of the available CocoaPods that esentially deal with the same thing, often with additional capabilities or sugar like enumeration for all the icons.
The idea is to prepare the string that will contain the star icon multiple times, first few highlighted (filled), the rest greyed out or not filled. We need to find the appropriate Unicode numbers for our interesting icons, first - everything we need is here:
I decided to use the basic
fa-star icon (
\uf005) and manipulate with the color, making the inactive gray. You might want to use
fa-star-o instead (
Now I need to create two formattings - first that represents the highlighted stars that will be black in my case and the second for the not highlighted ones - light gray, let’s say.
NSAttributedString expects me to provide the dictionaries with the appropriate options. Here they are:
Now, all I need is to build the actual string by iterating the appropriate number of times, first adding the highlighted stars, then filling with the inactive ones up to the expected number of stars.
Now it’s just a matter of wrapping it in a nice function:
To use it, we now just need an ordinary
And here is the result: