默认情况下,如果从屏幕的左边缘向右拖动,它将拖离ViewController并将其从堆栈中取出.
我想将此功能扩展到整个屏幕.当用户在任何地方拖动时,我也希望发生同样的事情.
我知道我可以实现向右滑动手势并简单地调用 self.navigationController?.popViewControllerAnimated(true)
但是,没有"拖动"动作.我希望用户能够右键拖动视图控制器,就好像它是一个对象,揭示了底层的内容.并且,如果它被拖过50%,则将其解雇.(看看Instagram,看看我的意思.)
War*_*shi 28
在Github制作了一个演示项目
https://github.com/rishi420/SwipeRightToPopController
我用过UIViewControllerAnimatedTransitioning协议
来自doc:
//这用于百分比驱动的交互式转换,以及容器控制器......
UIPanGestureRecognizer在控制器的视图中添加了一个.这是手势的动作:
func handlePanGesture(panGesture: UIPanGestureRecognizer) {
let percent = max(panGesture.translationInView(view).x, 0) / view.frame.width
switch panGesture.state {
case .Began:
navigationController?.delegate = self
navigationController?.popViewControllerAnimated(true)
case .Changed:
percentDrivenInteractiveTransition.updateInteractiveTransition(percent)
case .Ended:
let velocity = panGesture.velocityInView(view).x
// Continue if drag more than 50% of screen width or velocity is higher than 1000
if percent > 0.5 || velocity > 1000 {
percentDrivenInteractiveTransition.finishInteractiveTransition()
} else {
percentDrivenInteractiveTransition.cancelInteractiveTransition()
}
case .Cancelled, .Failed:
percentDrivenInteractiveTransition.cancelInteractiveTransition()
default:
break
}
}
Run Code Online (Sandbox Code Playgroud)
脚步:
.Begin:指定要执行的segue和分配UINavigationController委托.将需要代表InteractiveTransitioning.Changed: 具有百分比的UpdateInteractiveTransition.Ended: 如果拖动50%或更高或更高的速度,则继续保持转换.Cancelled, .Failed: 取消过渡参考文献:
创建平移手势识别器并移动交互式弹出手势识别器的目标。
将您的识别器添加到推送的视图控制器的 viewDidLoad 中,瞧!
编辑:使用更详细的解决方案更新了代码。
import os
import UIKit
public extension UINavigationController {
func fixInteractivePopGestureRecognizer(delegate: UIGestureRecognizerDelegate) {
guard
let popGestureRecognizer = interactivePopGestureRecognizer,
let targets = popGestureRecognizer.value(forKey: "targets") as? NSMutableArray,
let gestureRecognizers = view.gestureRecognizers,
// swiftlint:disable empty_count
targets.count > 0
else { return }
if viewControllers.count == 1 {
for recognizer in gestureRecognizers where recognizer is PanDirectionGestureRecognizer {
view.removeGestureRecognizer(recognizer)
popGestureRecognizer.isEnabled = false
recognizer.delegate = nil
}
} else {
if gestureRecognizers.count == 1 {
let gestureRecognizer = PanDirectionGestureRecognizer(axis: .horizontal, direction: .right)
gestureRecognizer.cancelsTouchesInView = false
gestureRecognizer.setValue(targets, forKey: "targets")
gestureRecognizer.require(toFail: popGestureRecognizer)
gestureRecognizer.delegate = delegate
popGestureRecognizer.isEnabled = true
view.addGestureRecognizer(gestureRecognizer)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
public enum PanAxis {
case vertical
case horizontal
}
public enum PanDirection {
case left
case right
case up
case down
case normal
}
public class PanDirectionGestureRecognizer: UIPanGestureRecognizer {
let axis: PanAxis
let direction: PanDirection
public init(axis: PanAxis, direction: PanDirection = .normal, target: AnyObject? = nil, action: Selector? = nil) {
self.axis = axis
self.direction = direction
super.init(target: target, action: action)
}
override public func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesMoved(touches, with: event)
if state == .began {
let vel = velocity(in: view)
switch axis {
case .horizontal where abs(vel.y) > abs(vel.x):
state = .cancelled
case .vertical where abs(vel.x) > abs(vel.y):
state = .cancelled
default:
break
}
let isIncrement = axis == .horizontal ? vel.x > 0 : vel.y > 0
switch direction {
case .left where isIncrement:
state = .cancelled
case .right where !isIncrement:
state = .cancelled
case .up where isIncrement:
state = .cancelled
case .down where !isIncrement:
state = .cancelled
default:
break
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
例如,在您的集合视图中:
open override func didMove(toParent parent: UIViewController?) {
navigationController?.fixInteractivePopGestureRecognizer(delegate: self)
}
Run Code Online (Sandbox Code Playgroud)
// MARK: - UIGestureRecognizerDelegate
extension BaseCollection: UIGestureRecognizerDelegate {
public func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer
) -> Bool {
otherGestureRecognizer is PanDirectionGestureRecognizer
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7428 次 |
| 最近记录: |