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

SwiftUI点击放大按钮出现异常不必要动画问题求助

问题解决:SwiftUI按钮点击异常动画修复

你的问题核心在于两点:状态变更未绑定动画,且固定宽度的父容器引发布局冲突,触发了SwiftUI的视图重建逻辑,才会出现按钮消失、尺寸动画怪异的情况;onGeometryChange误报也是布局约束冲突导致的无意义重绘。

修复后的代码

struct GrowingButton: View {
    var axis: Axis.Set = .vertical
    @State private var size: CGFloat = 1

    var width: CGFloat {
        axis.contains(.horizontal) ? 50.0 + 50.0 * size : 100
    }

    var height: CGFloat {
        axis.contains(.vertical) ? 50.0 + 50.0 * size : 100
    }
    
    var body: some View {
        Button {
            // 给状态变更绑定动画,让尺寸变化平滑过渡
            withAnimation(.easeInOut(duration: 0.3)) {
                size += 1
            }
        } label: {
            Text("\(size)")
                .padding()
                .frame(width: width, height: height)
                .background(Color.gray)
                .cornerRadius(8) // 可选,优化视觉效果
        }
    }
}

struct TestView: View {
    var body: some View {
        // 移除外层固定宽度frame,避免布局冲突;如需限制宽度,改用maxWidth
        HStack {
            GrowingButton(axis: .horizontal)
            GrowingButton(axis: .horizontal)
        }
        .padding()
        .frame(maxWidth: 400) // 可选,设置最大宽度而非固定宽度
    }
}

关键修复说明

  • 绑定显式动画:用withAnimation包裹size += 1,让状态变化驱动的尺寸修改拥有平滑过渡,避免突变触发视图重建。
  • 调整布局约束:移除外层固定宽度的frame(width:230)——按钮放大后会超出该宽度,引发布局异常进而导致视图销毁重建。若必须限制容器宽度,改用maxWidth允许内部视图在不超过上限的范围内自适应。
  • 若需保留固定宽度容器,可给内部HStack添加横向滚动,避免布局挤压:
struct TestView: View {
    var body: some View {
        HStack {
            ScrollView(.horizontal) {
                HStack {
                    GrowingButton(axis: .horizontal)
                    GrowingButton(axis: .horizontal)
                }
            }
        }
        .frame(width: 230, height: 100)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 07:47:13