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)
}