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

SwiftUI问题:长按填充按钮显示进度的实现优化

解决方案

针对你提到的两个问题,这里给出重构后的实现方案,直接解决填充区域匹配和点击区域扩展的问题:

修改后的完整代码

struct ContentView2: View {
    @State var isComplete: Bool = false
    @State var isSuccess: Bool = false
    
    var body: some View {
        VStack {
            Button(action: {}, label: {
                ZStack(alignment: .leading) {
                    // 进度填充层
                    RoundedRectangle(cornerRadius: 12)
                        .fill(isSuccess ? Color.clear : Color.red.opacity(0.5))
                        .frame(maxWidth: isComplete ? .infinity : 0)
                        .frame(maxHeight: .infinity) // 自动匹配按钮高度,无需硬编码
                    
                    // 按钮内容
                    VStack {
                        Image(systemName: "multiply.circle.fill")
                            .font(.system(size: 24, weight: .regular))
                            .foregroundColor(.red)
                        Text("Hold to End")
                            .font(.footnote)
                    }
                }
                .frame(height: 55) // 统一设置按钮整体高度(也可根据内容自适应)
                .frame(maxWidth: .infinity)
            })
            .buttonStyle(.plain) // 移除系统默认按钮样式,避免布局干扰
            .onLongPressGesture(minimumDuration: 1.0, maximumDistance: 50) {
                withAnimation(.easeInOut) {
                    isSuccess = true
                    // 执行你的业务操作
                }
            } onPressingChanged: { isPressing in
                if isPressing {
                    withAnimation(.easeIn(duration: 1.0)) {
                        isComplete = true
                    }
                } else {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                        if !isSuccess {
                            withAnimation(.easeInOut) {
                                isComplete = false
                            }
                        }
                    }
                }
            }
        }
        .padding() // 可选,避免内容贴边
    }
}

#Preview {
    ContentView2()
}

关键修改点说明

解决填充区域边界不匹配问题

  • 将进度条和按钮内容放入同一个ZStack,并作为Button的Label内容,确保进度条尺寸完全跟随Button的实际大小
  • 用.frame(maxHeight: .infinity)替代硬编码的高度值,让进度条自动匹配按钮的高度,无需手动同步尺寸
  • 保持进度条的圆角与按钮布局容器一致,避免填充区域超出按钮边界

解决点击区域无法扩展问题

  • 把长按手势直接绑定到Button本身,而非内部的VStack,这样整个Button的范围都会响应长按操作
  • 给Button添加.frame(maxWidth: .infinity),让它占满父视图的可用宽度,点击区域自然扩展到左右两侧
  • 使用.buttonStyle(.plain)移除系统默认的按钮样式,避免系统样式限制点击区域或干扰自定义布局

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 01:12:14