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

UIPanGestureRecognizer适配代码添加UIView:长按创建的圆形无法拖拽移动

解决长按创建圆形并拖拽移动的问题

看起来你已经搞定了长按创建圆形的部分,卡壳在拖拽移动这一步对吧?核心问题大概率是没给圆形绑定拖拽手势,或者手势的位置更新逻辑没处理对。我给你梳理下完整的实现思路和代码:

1. 先定义必要的属性

在你的ViewController里先存好当前的圆形视图和按钮引用:

class ViewController: UIViewController {
    @IBOutlet weak var space: UIButton!
    // 保存当前创建的圆形,方便后续拖拽和移除
    private var currentCircle: UIView?
}

2. 给space按钮绑定长按手势

在viewDidLoad里初始化并添加长按手势:

override func viewDidLoad() {
    super.viewDidLoad()
    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
    space.addGestureRecognizer(longPress)
}

3. 处理长按:创建圆形+绑定拖拽手势

长按开始时生成圆形,同时给圆形加上拖拽手势,结束时移除圆形:

@objc private func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
    switch gesture.state {
    case .began:
        // 创建圆形视图
        let circleSize: CGFloat = 50
        let circle = UIView(frame: CGRect(x: 0, y: 0, width: circleSize, height: circleSize))
        circle.layer.cornerRadius = circleSize / 2
        circle.backgroundColor = .systemOrange
        // 设置圆形初始位置为长按的触摸点(转换到space的坐标系)
        let touchPos = gesture.location(in: space)
        circle.center = touchPos
        
        space.addSubview(circle)
        currentCircle = circle
        
        // 给圆形添加拖拽手势
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handleCirclePan(_:)))
        circle.addGestureRecognizer(panGesture)
        
    case .ended, .cancelled:
        // 手指离开时移除圆形
        currentCircle?.removeFromSuperview()
        currentCircle = nil
        
    default:
        break
    }
}

4. 处理拖拽:让圆形跟着手指动

这一步是核心,要正确计算拖拽偏移量并更新圆形位置:

@objc private func handleCirclePan(_ gesture: UIPanGestureRecognizer) {
    guard let circle = gesture.view else { return }
    // 获取相对于space按钮的拖拽偏移量
    let translation = gesture.translation(in: space)
    // 更新圆形中心位置
    circle.center = CGPoint(x: circle.center.x + translation.x, y: circle.center.y + translation.y)
    // 重置偏移量,避免下次拖拽时累加
    gesture.setTranslation(.zero, in: space)
    
    // 如果拖拽结束(手指离开),同样移除圆形
    if gesture.state == .ended || gesture.state == .cancelled {
        circle.removeFromSuperview()
        currentCircle = nil
    }
}

关键注意点

  • 一定要把拖拽手势绑在圆形视图本身,而不是space按钮,这样拖拽时才会精准响应圆形的移动。
  • 每次处理拖拽后要重置偏移量,不然偏移值会越累越大,导致圆形飞出去。
  • 要覆盖长按和拖拽的所有结束状态(.ended、.cancelled),确保手指离开时圆形一定会被移除。

按照这个代码改完,圆形应该就能跟着你的拖拽顺畅移动啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:11:18