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

SwiftUI点击屏幕背景色切换延迟问题解决方案咨询

问题分析与解决方案

核心问题原因

  1. 手势冲突与响应延迟:同时给背景添加onTapGesture和DragGesture(minimumDistance:0),导致手势识别竞争;且DragGesture的onEnded在手指抬起时才触发事件,让背景色切换时机滞后,视觉上显得变慢。
  2. Balloon数组管理错误:通过position判断删除Balloon,若多次点击同一位置会导致删除逻辑失效,Balloon持续堆积,视图渲染压力增大,进一步拖慢界面响应。

修复后的完整代码

import SwiftUI

struct Balloon: Identifiable {
    let id = UUID()
    var position: CGPoint
    var text: String
    var textColor: Color
}

struct TryPage: View {
    @State private var displayName = "MeNaCa"
    @State private var backgroundColor = Color.black
    @State private var tapCount = UserDefaults.standard.integer(forKey: "tapCount")
    @State private var balloons: [Balloon] = []

    var body: some View {
        NavigationStack {
            ZStack {
                backgroundColor
                    .edgesIgnoringSafeArea(.all)
                    // 用DragGesture直接处理触摸,避免手势冲突
                    .gesture(
                        DragGesture(minimumDistance: 0)
                            .onChanged { value in
                                // 触摸开始时立即响应,提升速度
                                handleTap(location: value.location)
                            }
                    )
                
                Text(displayName)
                    .font(.largeTitle)
                    .fontWeight(.bold)
                    .foregroundColor(.white)
                
                ForEach(balloons) { balloon in
                    Text(balloon.text)
                        .foregroundColor(balloon.textColor)
                        .position(balloon.position)
                        .transition(.opacity)
                        .animation(.easeOut(duration: 0.2), value: balloon)
                }
            }
        }.background(ContentViewBindingView(bindingDisplayName: $displayName))
    }

    func handleTap(location: CGPoint?) {
        guard let location = location else { return }
        
        // 创建Balloon并记录唯一id
        let newBalloon = Balloon(position: location, text: "+1", textColor: self.textColorForBackground(self.backgroundColor))
        balloons.append(newBalloon)
        
        changeBackgroundColor()
        incrementTapCount()
        triggerHapticFeedback()
        
        // 通过唯一id删除Balloon,避免位置判断错误
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            if let index = self.balloons.firstIndex(where: { $0.id == newBalloon.id }) {
                withAnimation {
                    self.balloons.remove(at: index)
                }
            }
        }
    }
    
    func changeBackgroundColor() {
        backgroundColor = Color(
            red: .random(in: 0...1),
            green: .random(in: 0...1),
            blue: .random(in: 0...1)
        )
    }

    func incrementTapCount() {
        tapCount += 1
        UserDefaults.standard.set(tapCount, forKey: "tapCount")
    }

    func triggerHapticFeedback() {
        let generator = UIImpactFeedbackGenerator(style: .medium)
        generator.impactOccurred()
    }
    
    func textColorForBackground(_ background: Color) -> Color {    
        let brightness = background.luminance
        return brightness > 0.5 ? .black : .white
    }
}

extension Color {
    var components: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        let uiColor = UIColor(self)
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        return (red, green, blue, alpha)
    }
    
    var luminance: Double {
        let (red, green, blue, _) = self.components
        return (0.2126 * Double(red) + 0.7152 * Double(green) + 0.0722 * Double(blue))
    }
}

关键修复点

  • 优化手势处理:移除冗余的onTapGesture,将DragGesture的事件触发从onEnded改为onChanged,让操作在触摸开始时立即响应,消除延迟感。
  • 修复Balloon删除逻辑:通过Balloon的唯一id而非position查找并删除元素,避免因重复点击同一位置导致的Balloon堆积,减轻视图渲染压力。
  • 添加动画优化:给Balloon的移除操作添加withAnimation,让气泡消失更平滑,同时避免视图重绘的突兀感。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 10:05:56