我使用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
}
```
答案 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
}
}
}