You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI 4 - iOS 16:星级评分视图出现异常动画问题

星级评分视图重绘异常的解决方案

问题说明

以下代码实现的星级评分视图,在iOS 16中点击空心星会出现异常重绘动画,iOS 15.5中则存在轻微闪烁现象:

struct ContentView: View {
    @State var rating: Float = 1.0
    
    var body: some View {
        HStack(spacing: 4) {
            ForEach (0 ..< filledStarsCount, id: \.self) { index in
                Button {
                    rating = Float(index + 1)
                    
                } label: {
                    Image(systemName: "star.fill")
                }
              
            }
            
            ForEach (0 ..< emptyStarsCount, id: \.self) { index in
                Button {
                    rating = Float(index + filledStarsCount + 1)
                    
                } label: {
                    Image(systemName: "star")
                }
               
            }
        }
        .font(.title)
    }

    var emptyStarsCount: Int {
        filledStarsCount == 5 ? 0 : abs(5 - filledStarsCount  )
    }
    
    var filledStarsCount: Int {
        let rounded = Int(rating)
        if rounded > 5 { 
            return 5
        }
        else {
            return rounded
        }
    }
}

问题演示动图

问题根源

原代码通过两个动态ForEach分别渲染填充和空心星星,每次评分变化时,两个ForEach的元素数量会改变,SwiftUI会销毁旧视图并创建新视图,进而触发不必要的重绘动画或闪烁。

修复代码

改为固定渲染5个星星,通过当前索引与评分的关系控制星星的填充状态,避免视图的销毁重建:

struct ContentView: View {
    @State var rating: Float = 1.0
    
    var body: some View {
        HStack(spacing: 4) {
            ForEach(1...5, id: \.self) { starIndex in
                Button {
                    rating = Float(starIndex)
                } label: {
                    Image(systemName: starIndex <= Int(rating) ? "star.fill" : "star")
                }
            }
        }
        .font(.title)
    }
}

效果说明

这种实现方式下,所有星星视图始终存在,仅切换图片资源来更新状态,SwiftUI只会更新图片内容,不会触发视图重建,彻底解决重绘动画和闪烁问题,同时代码更简洁易维护。

内容的提问来源于stack exchange,提问作者JAHelia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 04:55:18