UIPanGesture设置边界

时间:2018-08-01 10:14:09

标签: ios swift uipangesturerecognizer

我使用UIPanGesture,在目标方法中,监听state,设置可以移动的最大值和最小值; 在changed状态下,当我检测到视图的view.origin.y超过myOrigin.y时,view.origin.y = myOrigin.y。缓慢拖动视图时,这似乎不是问题,但是当我快速拖动视图时,视图将超出此边界,然后立即变为我设置的边界,看起来像是在闪烁。如果我设置动画UIView.animation;它不会眨眼,但是很明显,我已经超越了极限,返回到此操作。 我想知道如何避免这种情况。无论拖动速度有多快,它都会停在我设置的边界处,并且不会超出边界然后返回。至少看起来像这样

```

  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
  }

```

1 个答案:

答案 0 :(得分:0)

您可以使用约束来做到这一点-这更加简单和灵活。

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

关键是使用centerYAnchor约束,优先级为750(.defaultHigh),以及>= 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
        }

    }

}