UIPanGesture 设置边界
UIPanGesture set boundary
我用的是UIPanGesture,在target方法中,监听state
,我设置了可以移动的最大值和最小值;
在changed
状态下,当我检测到view的view.origin.y
超过了myOrigin.y
,view.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
}
}
}
我用的是UIPanGesture,在target方法中,监听state
,我设置了可以移动的最大值和最小值;
在changed
状态下,当我检测到view的view.origin.y
超过了myOrigin.y
,view.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
}
}
}