Star Rating in Swift

Posted on

Problem

So I needed a a star rating feature to appear in my app – it doesn’t need to be interactive.

I have my app connected to a database I’ve set up in Parse, and I’ve made a column for OurRatingof type Number, and I just set a number between 0.5 and 5.

In my custom cell, I have 5 images which will display my star images. The code I’ve done is as follows:

//I define my images at the top

var fullStarImage: UIImage = UIImage(named: "starFull.png")!
var halfStarImage: UIImage = UIImage(named: "starHalf.png")!
var emptyStar: UIImage = UIImage(named: "starEmpty.png")!

Then further down in my table method, I have:

//Star Rating System
    if let ourRating = object?["OurRating"] as? Double {

    if ourRating == 0.5 {
        cell?.star1.image = halfStarImage
    }
    if ourRating == 1 {
        cell?.star1.image = fullStarImage
    }
    if ourRating == 1.5 {
        cell?.star1.image = fullStarImage
        cell?.star2.image = halfStarImage
    }
    if ourRating == 2 {
        cell?.star1.image = fullStarImage
        cell?.star2.image = fullStarImage
    }
    if ourRating == 2.5 {
        cell?.star1.image = fullStarImage
        cell?.star2.image = fullStarImage
        cell?.star3.image = halfStarImage
    }
    if ourRating == 3 {
        cell?.star1.image = fullStarImage
        cell?.star2.image = fullStarImage
        cell?.star3.image = fullStarImage
    }
    if ourRating == 3.5 {
        cell?.star1.image = fullStarImage
        cell?.star2.image = fullStarImage
        cell?.star3.image = fullStarImage
        cell?.star4.image = halfStarImage
    }
    if ourRating == 4 {
        cell?.star1.image = fullStarImage
        cell?.star2.image = fullStarImage
        cell?.star3.image = fullStarImage
        cell?.star4.image = fullStarImage
    }
    if ourRating == 4.5 {
        cell?.star1.image = fullStarImage
        cell?.star2.image = fullStarImage
        cell?.star3.image = fullStarImage
        cell?.star4.image = fullStarImage
        cell?.star5.image = halfStarImage
    }
    if ourRating == 5 {
        cell?.star1.image = fullStarImage
        cell?.star2.image = fullStarImage
        cell?.star3.image = fullStarImage
        cell?.star4.image = fullStarImage
        cell?.star5.image = fullStarImage
    }

}

This code WORKS! Nothing wrong with what it produces, I’m using wondering if there was a better way I could have written this? Maybe to reduce the amount of code?

Any advice is appreciated.

Solution

You could create a helper routine getStarImage:forRating: and use that to set up each star:

let fullStarImage:  UIImage = UIImage(named: "starFull.png")!
let halfStarImage:  UIImage = UIImage(named: "starHalf.png")!
let emptyStarImage: UIImage = UIImage(named: "starEmpty.png")!

func getStarImage(starNumber: Double, forRating rating: Double) -> UIImage {
    if rating >= starNumber {
        return fullStarImage
    } else if rating + 0.5 == starNumber {
        return halfStarImage
    } else {
        return emptyStarImage
    }
}

if let ourRating = object?["OurRating"] as? Double {
    cell?.star1.image = getStarImage(1, forRating: ourRating)
    cell?.star2.image = getStarImage(2, forRating: ourRating)
    cell?.star3.image = getStarImage(3, forRating: ourRating)
    cell?.star4.image = getStarImage(4, forRating: ourRating)
    cell?.star5.image = getStarImage(5, forRating: ourRating)
}

If the last part looks a bit redundant, you could do it in a loop. This probably isn’t worth it for 5 items, but it demonstrates what you can do in Swift:

for (index, imageView) in [cell?.star1, cell?.star2, cell?.star3, cell?.star4, cell?.star5].enumerate() {
    imageView?.image = getStarImage(index + 1, forRating: ourRating)
}

Leave a Reply

Your email address will not be published. Required fields are marked *