Ios “我如何实施?”;拖动鼠标右键可解除“锁定”;一个视图控制器';导航堆栈中有什么?
默认情况下,如果从屏幕左边缘向右拖动,它将拖走ViewController并将其从堆栈中移除 我想将此功能扩展到整个屏幕。当用户拖动到任何地方时,我希望同样的情况发生 我知道我可以实现正确的滑动手势,只需调用Ios “我如何实施?”;拖动鼠标右键可解除“锁定”;一个视图控制器';导航堆栈中有什么?,ios,swift,Ios,Swift,默认情况下,如果从屏幕左边缘向右拖动,它将拖走ViewController并将其从堆栈中移除 我想将此功能扩展到整个屏幕。当用户拖动到任何地方时,我希望同样的情况发生 我知道我可以实现正确的滑动手势,只需调用self.navigationController?.popViewControllerAnimated(true) 但是,不存在“拖动”运动。我希望用户能够右键拖动视图控制器,就像它是一个对象一样,显示下面的内容。而且,如果超过50%,就驳回它。(请查看instagram,了解我的意思。)
self.navigationController?.popViewControllerAnimated(true)
但是,不存在“拖动”运动。我希望用户能够右键拖动视图控制器,就像它是一个对象一样,显示下面的内容。而且,如果超过50%,就驳回它。(请查看instagram,了解我的意思。)
在Github中制作了一个演示项目我使用了
UIViewControllerAnimatedTransitioning
协议
从文档:
//这用于百分比驱动的交互式转换,以及容器控制器
在控制器视图中添加了一个UIPangestureRecognitor
。这是手势的动作:
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
}
}
步骤:
.Begin:
指定要执行和分配的序列UINavigationController
委派。交互翻译需要委托人
.Changed:
使用百分比更新InteractiveTransition.end:
如果拖动速度大于等于50%或更高,则继续剩余的过渡,否则取消.Cancelled.。失败:
取消转换参考资料:
您需要调查
UINavigationController
的属性
下面是一个类似的问题,用示例代码将其连接起来
Swift 4版本@Warif Akhand Rishi接受的答案 尽管这个答案确实有效,但我发现了两个怪癖
class ViewController: UIGestureRecognizerDelegate, UINavigationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.interactivePopGestureRecognizer?.delegate = self
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
view.addGestureRecognizer(panGesture)
}
@objc func handlePanGesture(_ gesture: UIPanGestureRecognizer){
let interactiveTransition = UIPercentDrivenInteractiveTransition()
let percent = max(gesture.translation(in: view).x, 0) / view.frame.width
switch gesture.state {
case .began:
navigationController?.delegate = self
// *** use this if the vc is PUSHED on the stack **
navigationController?.popViewController(animated: true)
// *** use this if the vc is PRESENTED **
//navigationController?.dismiss(animated: true, completion: nil)
case .changed:
interactiveTransition.update(percent)
case .ended:
let velocity = gesture.velocity(in: view).x
// Continue if drag more than 50% of screen width or velocity is higher than 1000
if percent > 0.5 || velocity > 1000 {
interactiveTransition.finish()
} else {
interactiveTransition.cancel()
}
case .cancelled, .failed:
interactiveTransition.cancel()
default:break
}
}
}
向右滑动以关闭视图控制器 Swift 5版本- (从右向左滑动时,也删除了手势识别) 重要- 在VC2的“属性检查器”中,将“演示”值从“全屏”设置为“全屏”。这将允许VC1在通过手势解除VC2时可见 — 没有它,VC2后面将出现黑屏,而不是VC1
class ViewController: UIGestureRecognizerDelegate, UINavigationControllerDelegate {
var initialTouchPoint: CGPoint = CGPoint(x: 0, y: 0)
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.interactivePopGestureRecognizer?.delegate = self
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
view.addGestureRecognizer(panGesture)
}
@objc func handlePanGesture(_ sender: UIPanGestureRecognizer) {
let touchPoint = sender.location(in: self.view?.window)
let percent = max(sender.translation(in: view).x, 0) / view.frame.width
let velocity = sender.velocity(in: view).x
if sender.state == UIGestureRecognizer.State.began {
initialTouchPoint = touchPoint
} else if sender.state == UIGestureRecognizer.State.changed {
if touchPoint.x - initialTouchPoint.x > 0 {
self.view.frame = CGRect(x: touchPoint.x - initialTouchPoint.x, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
}
} else if sender.state == UIGestureRecognizer.State.ended || sender.state == UIGestureRecognizer.State.cancelled {
if percent > 0.5 || velocity > 1000 {
navigationController?.popViewController(animated: true)
} else {
UIView.animate(withDuration: 0.3, animations: {
self.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
})
}
}
}
}
希望这有帮助。
如有必要,请随时提出更改建议。创建平移手势识别器,并将交互式pop手势识别器的目标移动到不同的位置 将您的识别器添加到推送视图控制器的viewDidLoad中,瞧 编辑:用更详细的解决方案更新了代码
导入操作系统
导入UIKit
公共扩展UINavigationController{
func FixInteractiveProgTestureRecognitor(委托:UIGestureRecognitzerDelegate){
警卫
让popGestureRecognizer=interactivePopGestureRecognizer,
将targets=popGestureRecognitor.value(forKey:“targets”)设为?NSMutableArray,
让gestureRecognizers=view.gestureRecognizers,
//swiftlint:禁用空\u计数
目标计数>0
else{return}
如果viewControllers.count==1{
对于手势识别器中的识别器,其中识别器为泛方向手势识别器{
view.RemovegestureRecognitor(识别器)
PopGestureRecognitor.isEnabled=false
recognizer.delegate=nil
}
}否则{
如果gestureRecognizers.count==1{
让gestureRecognizer=PanDirectionGestureRecognizer(轴:。水平,方向:。右侧)
gestureRecognizer.cancelsTouchesInView=false
GestureRecognitor.setValue(目标,forKey:“目标”)
手势识别器.require(toFail:popGestureRecognizer)
gestureRecognizer.delegate=委托
PopGestureRecognitor.isEnabled=true
view.addGestureRecognizer(gestureRecognizer)
}
}
}
}
公共枚举泛轴{
垂直箱
案例水平
}
公共枚举泛方向{
案例左
案例权利
开箱
结案
正常情况
}
公共类PanDirectionGestureRecognitor:UIPangestureRecognitor{
让轴:泛轴
方向:泛方向
public init(轴:泛轴,方向:泛方向=.normal,目标:AnyObject?=nil,操作:选择器?=nil){
self.axis=轴
方向
super.init(目标:目标,操作:操作)
}
覆盖公共函数触摸移动(touch:Set,带有事件:UIEvent){
super.touchesMoved(touches,with:event)
如果状态==。开始{
设vel=速度(在:视图中)
开关轴{
壳体水平,其中abs(y级)>abs(x级):
状态=。已取消
壳体垂直,其中abs(x级)>abs(y级):
状态=。已取消
违约:
打破
}
设isIncrement=轴==水平?x级>0:y级>0
开关方向{
案例。左侧为增量:
状态=。已取消
案例。正确位置!i增加:
状态=。已取消
案例。增加的地方:
状态=。已取消
case.down where!i增量:
状态=。已取消
违约:
打破
}
}
}
}
例如,在集合视图中:
open override func didMove(toParent父对象:UIViewController?){
navigationController?.FixInteractiveProgTestureRecognitor(代理:self)
}
我认为这比建议的解决方案更简单,而且也适用于导航中的所有ViewController以及嵌套的scrollvi
// MARK: - UIGestureRecognizerDelegate
extension BaseCollection: UIGestureRecognizerDelegate {
public func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer
) -> Bool {
otherGestureRecognizer is PanDirectionGestureRecognizer
}
}