UIPanGesture 设置边界

UIPanGesture set boundary

我用的是UIPanGesture,在target方法中,监听state,我设置了可以移动的最大值和最小值; 在changed状态下,当我检测到view的view.origin.y超过了myOrigin.yview.origin.y = myOrigin.y。慢慢拖view的时候,好像没什么问题,但是当我快速拖view的时候,view就会越过这个边界,然后立马变成我设置的边界,好像在闪烁。如果我设置动画 UIView.animation;它不会眨眼,但很明显,我越界了,return 对此操作。 我想知道如何避免这种情况。不管拖得多快,都会停在我设置的边界上,不会超出边界然后return.at至少是这样

```

  let point = pan.translation(in: view)
  switch pan.state {
    case .began:
        break
    case .changed:
        view.frame.origin.y = view.frame.origin.y + point.y
        if view.frame.origin.y > 200{
          view.frame.origin.y = 200
        }
        pan.setTranslation(.zero, in: view)
    default :
    break
  }

```

您可以使用约束来执行此操作 - 这更简单、更灵活。

此代码将在视图控制器的中心创建一个 100 x 100 蓝色视图,允许拖动它(通过 PanGesture),并将其垂直移动限制为 200 磅视图顶部(距离底部 20 磅,因此您不能将其向下拖出屏幕)。

关键是使用优先级为750(.defaultHigh)的centerYAnchor约束,以及>= topAnchor<= bottomAnchor约束来限制垂直定位。

//
//  PanLimitViewController.swift
//
//  Created by Don Mag on 8/1/18.
//

import UIKit

class PanLimitViewController: UIViewController {

    // blue view for panning (dragging)
    var panView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .blue
        return v
    }()

    // the panView's center y constraint
    var panCenterYConstraint: NSLayoutConstraint!

    // var to track the current center y
    var currentCenterYConstant: CGFloat = 0.0

    // pan gesture recognizer
    var panGesture  = UIPanGestureRecognizer()

    override func viewDidLoad() {
        super.viewDidLoad()

        // add the panView
        view.addSubview(panView)

        // constrain width to 100, height equal to width
        panView.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
        panView.heightAnchor.constraint(equalTo: panView.widthAnchor).isActive = true

        // constrain to center horizontally
        panView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

        // initialize panView's center y constraint to center of view
        panCenterYConstraint = NSLayoutConstraint(
            item: panView,
            attribute: .centerY,
            relatedBy: .equal,
            toItem: view,
            attribute: .centerY,
            multiplier: 1.0,
            constant: 0.0)

        // set panView's center y constraint priority to 750
        // required to allow dragging
        panCenterYConstraint.priority = .defaultHigh

        // activate panView's center y constraint
        panCenterYConstraint.isActive = true

        // set panView's topAnchor to >= view's top + 200
        // this will prevent dragging it higher than 200 pts from the top
        panView.topAnchor.constraint(greaterThanOrEqualTo: view.topAnchor, constant: 200.0).isActive = true

        // set panView's bottomAnchor to <= view's bottom
        // this will prevent dragging it below the bottom
        panView.bottomAnchor.constraint(lessThanOrEqualTo: view.bottomAnchor, constant: -20.0).isActive = true

        // create pan gesture and add to panView
        panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.panGestureHandler(_:)))
        panView.addGestureRecognizer(panGesture)

    }

    @objc func panGestureHandler(_ recognizer: UIPanGestureRecognizer){

        switch recognizer.state {
        case .began:
            // save the current center y constant value
            currentCenterYConstant = panCenterYConstraint.constant
            break

        case .changed:
            // update panView's center y, based on drag
            let translation = recognizer.translation(in: self.view)
            panCenterYConstraint.constant = currentCenterYConstant + translation.y
            break

        case .ended, .cancelled:
            // update panView's center y when drag is finished
            panCenterYConstraint.constant = panView.center.y - view.center.y
            break

        default:
            break
        }

    }

}