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

SwiftUI实现单次点击按钮后自动触发插入动画再执行移除动画的方法

实现单次点击触发弹窗先显示再自动隐藏的SwiftUI方案

嘿,这个需求其实很好解决!核心思路就是让弹窗在完成插入动画后,自动延迟触发关闭的状态切换,同时保证关闭时的移除动画也能正常执行。我帮你调整了代码,下面是完整的实现:

import SwiftUI

struct ParentView: View {
    // 遵循Swift命名规范,改成小驼峰命名更易读
    @State private var isWidgetSelectionShown: Bool = false
    
    var body: some View {
        ZStack {
            Rectangle()
                .fill(.white)
                .zIndex(0)
            
            Button("Show Popup") {
                withAnimation {
                    // 先触发弹窗显示的插入动画
                    isWidgetSelectionShown = true
                }
                
                // 延迟一段时间(可根据动画时长调整)后自动触发关闭的移除动画
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    withAnimation {
                        isWidgetSelectionShown = false
                    }
                }
            }
            
            if isWidgetSelectionShown {
                PopupPage() // 结构体名首字母大写,遵循Swift规范
            }
        }
        .frame(width: 300, height: 300, alignment: .center)
    }
}

// 结构体名首字母大写,符合Swift命名规范
struct PopupPage: View {
    var body: some View {
        ZStack {
            Rectangle()
                .fill(.green)
                .zIndex(0)
            Text("This is a popup")
        }
        .transition(.asymmetric(insertion: .scale, removal: .opacity))
        .frame(width: 200, height: 200, alignment: .center)
    }
}

关键修改点说明:

  • 恢复按钮交互逻辑:把你注释掉的按钮代码还原,点击时先通过withAnimation将状态设为true,触发弹窗的插入显示动画。
  • 自动延迟关闭:用DispatchQueue.main.asyncAfter设置一个延迟(这里设为0.5秒,你可以根据动画实际时长调整),等插入动画完全结束后,再通过withAnimation将状态设为false,触发移除隐藏动画。
  • 命名规范优化:把原代码中的WidgetSelectionShowState改成isWidgetSelectionShown,popupPage改成PopupPage,这是Swift官方推荐的命名方式,让代码更易读和维护。

这样修改后,你只需要点击一次按钮,弹窗就会先以scale动画显示,然后自动以opacity动画隐藏,完全符合你的需求~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 08:37:29