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

SwiftUI 如何实现类iOS静音模式的HUD弹窗及图标动画效果

你可以通过新增状态变量控制动画触发,结合SwiftUI内置动画修饰符实现需求,修改后的完整代码如下:

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        PopOver(image: "speaker.slash.fill", color: .gray, title: "静音已开启")
    }
}

struct PopOver: View{
    var image: String
    var color: Color
    var title: String

    @Environment(\.colorScheme) var scheme
    // 控制图标动画状态
    @State private var animateIcon = false
    // 控制HUD垂直偏移,初始在屏幕外
    @State private var offsetY: CGFloat = -100
    
    var body: some View{
        HStack(spacing: 10){
            Image(systemName: image)
                .font(.title3)
                .foregroundColor(color)
                // 以下两种动画效果二选一即可
                // 效果1:沿Y轴旋转180度
                .rotation3DEffect(.degrees(animateIcon ? 180 : 0), axis: (x: 0, y: 1, z: 0))
                // 效果2:左右轻微晃动10度
                // .rotationEffect(.degrees(animateIcon ? -10 : 10))
            
            Text(title)
                .foregroundColor(.primary)
        }
        .padding(.vertical,10)
        .padding(.horizontal)
        .background(
            scheme == .dark ? Color.black : Color.white
        )
        .clipShape(Capsule())
        .shadow(color: Color.primary.opacity(0.1), radius: 5, x: 1, y: 5)
        .shadow(color: Color.primary.opacity(0.03), radius: 5, x: 0, y: -5)
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
        .offset(y: offsetY)
        .onAppear {
            // HUD从顶部滑入动画
            withAnimation(.easeOut(duration: 0.3)) {
                offsetY = 20
            }
            // 触发图标动画
            withAnimation(.easeInOut(duration: 0.4).repeatCount(1, autoreverses: true)) {
                animateIcon = true
            }
            // 停留2秒后HUD滑出消失
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                withAnimation(.easeIn(duration: 0.3)) {
                    offsetY = -100
                }
                // 重置状态方便下次触发
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                    animateIcon = false
                }
            }
        }
    }
}

如果需要在父视图中手动触发HUD展示,可以参考如下调用方式:

struct ContentView: View {
    // 控制HUD显隐状态
    @State private var showMuteHUD = false
    var body: some View {
        ZStack {
            Button("切换静音状态") {
                showMuteHUD = true
            }
            if showMuteHUD {
                PopOver(image: "speaker.slash.fill", color: .gray, title: "静音已开启")
                    .onDisappear {
                        // HUD消失后重置状态
                        showMuteHUD = false
                    }
            }
        }
    }
}

你可以根据需求调整动画时长、旋转角度、停留时间等参数,匹配你想要的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 22:54:04