自定义星级评分显示异常:4.2分未正确显示4满星1半星
星级评分显示异常问题
我在Storyboard中添加了5个UIImageView,关联的输出口如下:
@IBOutlet var starRatingImageViews: [UIImageView]!
从JSON获取的评分是字符串类型,示例为rating = "4.2"。预期显示4个满星+1个半星,但实际显示不符合预期,当前评分"4.2"对应的星星显示错误。
调用代码及fillStars方法如下:
@IBOutlet var starRatingImageViews: [UIImageView]! if let rating = Float(user.rating ?? "0.0") { rating.fillStars(in: starRatingImageViews) } func fillStars(in imageViews: [UIImageView], withEmptyStar color: UIColor = .darkGray) { for i in (0 ..< imageViews.count) { imageViews[i].contentMode = .scaleAspectFit let review = Int(Float(self)) if (i < review) { imageViews[i].image = UIImage(systemName: "star.fill")?.withRenderingMode(.alwaysOriginal).withTintColor(CommonColor.yellowColor) } else { if (self - Float(review)) > (0.5), i == review { imageViews[i].image = UIImage(systemName: "star.fill")?.withRenderingMode(.alwaysOriginal).withTintColor(CommonColor.yellowColor) } else if (self - Float(review)) <= (0.5), (self - Float(review)) > (0.0), i == review { imageViews[i].image = UIImage(systemName: "star.leadinghalf.fill")?.withRenderingMode(.alwaysOriginal).withTintColor(CommonColor.yellowColor) } else { imageViews[i].image = UIImage(systemName: "star")?.withRenderingMode(.alwaysOriginal).withTintColor(color) } } } }
请问fillStars方法存在哪些问题?
问题分析与修正
你的fillStars方法主要存在逻辑冗余、无范围限制两个核心问题,同时可以优化可读性:
关键问题点
- 未限制评分范围:若评分超过星星总数(比如6.0)或为负数,会出现索引越界或异常显示
- 逻辑嵌套冗余:重复计算差值、条件判断层级过多,易出错
- 变量命名不直观:
review这类命名无法清晰表达含义
修正后的代码
extension Float { func fillStars(in imageViews: [UIImageView], withEmptyStarColor color: UIColor = .darkGray) { let maxStars = Float(imageViews.count) // 限制评分在0到星星总数之间,避免异常 let clampedRating = max(0, min(self, maxStars)) // 计算满星数量 let fullStarCount = Int(clampedRating) // 计算剩余的小数部分评分 let remainder = clampedRating - Float(fullStarCount) for (index, imageView) in imageViews.enumerated() { imageView.contentMode = .scaleAspectFit if index < fullStarCount { // 显示满星 imageView.image = UIImage(systemName: "star.fill")? .withRenderingMode(.alwaysOriginal) .withTintColor(CommonColor.yellowColor) } else if index == fullStarCount, remainder > 0 { // 剩余评分>0.5时显示满星,否则显示半星 // 若需要右半星,将图标名改为"star.trailinghalf.fill" let starIconName = remainder > 0.5 ? "star.fill" : "star.leadinghalf.fill" imageView.image = UIImage(systemName: starIconName)? .withRenderingMode(.alwaysOriginal) .withTintColor(CommonColor.yellowColor) } else { // 显示空星 imageView.image = UIImage(systemName: "star")? .withRenderingMode(.alwaysOriginal) .withTintColor(color) } } } }
额外检查项
请确认starRatingImageViews数组在Storyboard中的顺序:数组第一个元素对应界面最左侧的星星,最后一个元素对应最右侧的星星,顺序颠倒会导致显示错位。
内容的提问来源于stack exchange,提问作者swift doubts
相关产品推荐
相关产品推荐

