LoginSignup
0
0

More than 1 year has passed since last update.

PanGestureの実装の注意点

Posted at

PanGestureの実装方法が間違っているのに最近気づいたため、備忘録として残します。

一つViewを作る

ViewController.swift
import UIKit

class ViewController: UIViewController {

    let blueView = {
        let view = UIView()
        view.backgroundColor = .blue
        
        return view
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(blueView)
        
        
    }
    
    override func viewDidLayoutSubviews() {
        blueView.frame = CGRect(x: 30, y: 30, width: 100, height: 50)
    }
}

次にPanGestureをつける

私はこんな感じで実装していました。一応動きます。

ViewController.swift

import UIKit

class ViewController: UIViewController {
    
    let blueView = {
        let view = UIView()
        view.backgroundColor = .blue
        
        return view
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //追加
        blueView.isUserInteractionEnabled = true
        
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.panGesture))
        blueView.addGestureRecognizer(panGesture)
        
        view.addSubview(blueView)
    }
    
    override func viewDidLayoutSubviews() {
        blueView.frame = CGRect(x: 30, y: 30, width: 100, height: 50)
    }

    //追加
    @objc func panGesture(sender: UIPanGestureRecognizer){
        let point = sender.location(in: view)
        let panGesture = sender.view
        panGesture?.center = point
        
    }
    
}

ただこれだとViewが小さいときは気にならないのですが、viewのサイズが大きい時(width :300, height:300くらい)ぎこちない動きになります。原因はこのpanGestureメソッドです。

@objc func panGesture(sender: UIPanGestureRecognizer){

        //①クリックした地点の座標を取得
        let point = sender.location(in: view)
        let panGesture = sender.view
        
        //②viewの中心座標をクリックした地点の座標に無理やり設定している
        panGesture?.center = point
        
    }

移動量を使おう

メソッドを以下のように変更するとスムーズに移動します。
@objc func panGesture(sender: UIPanGestureRecognizer){

        //viewをドラッグした時の移動量を取得
        let move = sender.translation(in: view)
        
        let panGesture = sender.view
        
        //移動量をviewの中心のx座標、y座標に足してあげます
        panGesture?.center.x += move.x
        panGesture?.center.y += move.y
        
        //最後に移動量をリセットしてあげます。この文がないとviewがどこかに飛んでいきます。
        sender.setTranslation(.zero, in: view)
        
    }

全体のコード

import UIKit

class ViewController: UIViewController {
    
    let blueView = {
        let view = UIView()
        view.backgroundColor = .blue
        
        return view
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        blueView.isUserInteractionEnabled = true
        
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.panGesture))
        blueView.addGestureRecognizer(panGesture)
        
        view.addSubview(blueView)
    }
    
    override func viewDidLayoutSubviews() {
        blueView.frame = CGRect(x: 30, y: 30, width: 300, height: 300)
    }

    
    @objc func panGesture(sender: UIPanGestureRecognizer){
        let move = sender.translation(in: view)
        
        let panGesture = sender.view
        
        panGesture?.center.x += move.x
        panGesture?.center.y += move.y
        
        sender.setTranslation(.zero, in: view)
        
    }
    
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0