我正在使用 Swift 制作一个 iOS8 应用程序。我希望用户能够使用手势来显示界面的某些部分。例如,用户向上滑动手指,他们向上滑动手指的视图就会移开,跟随手指显示下面的另一个视图。
我想要的是一个手势来给出类似于可以从屏幕顶部下拉的通知框的结果。我一直在查看文档,但似乎找不到合适的手势。
我看到一个名为 UISwipeGestureRecogniser 的工具,但唯一的问题是,它不跟随你的手指,它只是在我向上/向下滑动手指时运行一个功能。
这是文档页面: https://developer.apple.com/documentation/uikit/uigesturerecognizer
您正在寻找 UIPanGestureRecognizer。您可以在此处找到 Apple 文档。
这是一个示例处理程序,它将用手指移动视图。在 Interface Builder 中,将
UIPanGestureRecognizer
添加到您希望能够拖动的视图。将委托设置为您的 ViewController
。将动作设置为此动作:
斯威夫特2.X:
@IBAction func handlePan(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == .Began || gestureRecognizer.state == .Changed {
let translation = gestureRecognizer.translationInView(self.view)
// note: 'view' is optional and need to be unwrapped
gestureRecognizer.view!.center = CGPointMake(gestureRecognizer.view!.center.x + translation.x, gestureRecognizer.view!.center.y + translation.y)
gestureRecognizer.setTranslation(CGPointMake(0,0), inView: self.view)
}
}
斯威夫特3:
@IBAction func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
let translation = gestureRecognizer.translation(in: self.view)
// note: 'view' is optional and need to be unwrapped
gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x + translation.x, y: gestureRecognizer.view!.center.y + translation.y)
gestureRecognizer.setTranslation(CGPoint.zero, in: self.view)
}
}
当然,您可以通过编程方式添加
UIPanGestureRecognizer
:
在
viewDidLoad
中为您的 ViewController
创建识别器并将其添加到您希望能够拖动的视图中:
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
self.someDraggableView.addGestureRecognizer(gestureRecognizer)
并且为了避免滑动大于主视图的边距,此代码可以帮助您:
class TestPanGestureView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
self.addGestureRecognizer(gestureRecognizer)
}
@objc func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
let translation = gestureRecognizer.translation(in: self)
guard let parentController = self.parentContainerViewController(),
let navigationController = parentController.navigationController,
let gestureRecognizerView = gestureRecognizer.view else { return }
let fullWidth = parentController.view.frame.width
let fullHeight = parentController.view.frame.height
let navbarHeight = navigationController.navigationBar.frame.maxY
let bottomHeight: CGFloat = 160
var fullTranslationInX = gestureRecognizerView.center.x + translation.x
// Avoid sliding more than allowed on the right side in X
if fullTranslationInX > (fullWidth - (self.frame.width / 2)) {
fullTranslationInX = gestureRecognizer.view!.center.x
}
// Avoid sliding more than allowed on the left side in X
if fullTranslationInX < (self.frame.width / 2) {
fullTranslationInX = gestureRecognizer.view!.center.x
}
var fullTranslationInY = gestureRecognizerView.center.y + translation.y
// Avoid sliding more than allowed on the bottom side in Y
if fullTranslationInY > ((fullHeight - bottomHeight) - (self.frame.height / 2)) {
fullTranslationInY = gestureRecognizer.view!.center.y
}
// Avoid sliding more than allowed on the top side in Y
if fullTranslationInY < ( navbarHeight + (self.frame.height / 2)) {
fullTranslationInY = gestureRecognizer.view!.center.y
}
gestureRecognizerView.center = CGPoint(x: fullTranslationInX,
y: fullTranslationInY)
gestureRecognizer.setTranslation(CGPoint.zero, in: self)
}
}
}