iOS 15及以上SwiftUI自定义横幅通知双向动画实现
SwiftUI iOS15+ 恢复自定义横幅通知双向滑入滑出动画
要解决iOS15+下用animation(_:value:) API实现横幅双向动画的问题,核心是把动画修饰符和过渡效果的作用位置配对正确,以下是可行的实现方案:
完整代码示例
struct CustomBannerDemo: View { @State private var showBanner = false var body: some View { ZStack(alignment: .top) { // 页面主内容 VStack { Button("触发横幅") { showBanner.toggle() } .padding() Spacer() } // 自定义横幅视图 if showBanner { HStack { Image(systemName: "exclamationmark.circle") Text("这是一条自定义通知横幅") Spacer() } .padding(.horizontal, 16) .padding(.vertical, 12) .background(Color(.systemBlue)) .foregroundColor(.white) .cornerRadius(8) .padding(.horizontal, 16) .transition(.move(edge: .top)) // 定义滑入滑出的过渡方向 .animation(.easeInOut(duration: 0.3), value: showBanner) // 绑定状态变量触发双向动画 } } } }
关键注意事项
- 动画修饰符的位置:必须把
.animation(_:value:)直接附加在条件渲染的横幅视图上,而不是父容器(比如ZStack)。这样当showBanner状态变更时,系统才会针对这个视图的显示/隐藏触发过渡动画。 - 过渡效果配合:
.transition(.move(edge: .top))定义了视图显示时从顶部滑入、隐藏时滑回顶部的行为,和动画曲线结合后就能实现双向平滑动画。 - 状态变更时机:不管是通过按钮触发还是自动隐藏,确保
showBanner的状态修改都在主队列执行(SwiftUI默认在主队列,但异步操作时要注意),避免动画失效。
如果需要更自定义的动画曲线,直接修改.easeInOut的参数即可,比如调整duration来控制动画快慢。
内容的提问来源于stack exchange,提问作者JuvinR
相关产品推荐
相关产品推荐

