我想在ViewController(1)和NavigationViewController(2)之间进行交互式转换.

NavigationController由一个按钮调用,因此在呈现时没有交互式转换.它可以通过按钮或UIPanGestureRecognizer来解除,因此它可以被交互或不被解雇.

我有一个名为TransitionManager的对象,用于转换,UIPercentDrivenInteractiveTransition的子类.

下面的代码的问题是从不调用两个委托方法interactionControllerFor ….

此外,当我按下按钮或swip(UIPanGestureRecognizer)时,模态segue的基本动画就完成了.所以两个委托方法animationControllerFor …也不起作用.

有任何想法吗 ?谢谢

ViewController.swift

let transitionManager = TransitionManager()

override func viewDidLoad() {
    super.viewDidLoad()

    self.transitioningDelegate = transitionManager
}

override func prepareForSegue(segue: UIStoryboardSegue,sender: AnyObject?) {

        let dest = segue.destinationViewController as UIViewController
        dest.transitioningDelegate = transitionManager
        dest.modalPresentationStyle = .Custom
}

TransitionManager.swift

class TransitionPushManager: UIPercentDrivenInteractiveTransition,UINavigationControllerDelegate,UIViewControllerTransitioningDelegate {


@IBOutlet var navigationController: UINavigationController!

var animation : Animator! // Implement UIViewControllerAnimatedTransitioning protocol


override func awakeFromNib() {
    var panGesture = UIPanGestureRecognizer(target: self,action: "gestureHandler:")
    navigationController.view.addGestureRecognizer(panGesture)

    animation = Animator()
}

func gestureHandler(pan : UIPanGestureRecognizer) {

    switch pan.state {

    case .Began :

        interactive = true

            navigationController.presentingViewController?.dismissViewControllerAnimated(true,completion:nil)


    case .Changed :

        ...            

    default :

        ...

        interactive = false

    }

}


func animationControllerForPresentedController(presented: UIViewController,presentingController presenting: UIViewController,sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return animation
}

func animationControllerFordismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return animation
}

func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
    return nil
}

func interactionControllerFordismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
    return self.interactive ? self : nil
}

Main.storyboard

> ViewController上的按钮触发了一个模态segue来呈现NavigationController
> NavigationController的委托出口链接到TransitionManager类的对象
> NavigationController在TransitionManager类中由属性“navigationController”引用

解决方法

我认为关键问题是你在viewDidLoad中配置transitionDelegate.在这个过程中,这通常太晚了.您应该在初始化导航控制器时执行此操作.

让我们想象你的根场景(“Root”)呈现导航控制器场景(“Nav”),然后从场景A推送到B到C,例如,我想象一个这样的对象模型,导航控制器只会拥有自己的动画控制器,交互控制器和手势识别器:

这是您在考虑(a)“root”呈现“nav”时的自定义转换(非交互式)时所需要的; (b)当“nav”自行解散以返回“根”时的自定义转换(交互与否).所以,我将导航控制器子类化为:

>在其视图中添加手势识别器;
>设置transitioningDelegate以在从根场景转换到导航控制器场景(并返回)时生成自定义动画:
> transitioningDelegate还将返回交互控制器(仅在手势识别器正在进行时才存在),如果您在手势的上下文之外解除,则在手势和非交互式转换期间产生交互式转换.

在Swift 3中,它看起来像:

import UIKit
import UIKit.UIGestureRecognizerSubclass

class CustomNavigationController: UINavigationController {

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configure()
    }

    override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
        configure()
    }

    private func configure() {
        transitioningDelegate = self   // for presenting the original navigation controller
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        delegate = self                // for navigation controller custom transitions

        let left = UIScreenEdgePanGestureRecognizer(target: self,action: #selector(handleSwipeFromLeft(_:)))
        left.edges = .left
        view.addGestureRecognizer(left)
    }

    fileprivate var interactionController: UIPercentDrivenInteractiveTransition?

    func handleSwipeFromLeft(_ gesture: UIScreenEdgePanGestureRecognizer) {
        let percent = gesture.translation(in: gesture.view!).x / gesture.view!.bounds.size.width

        if gesture.state == .began {
            interactionController = UIPercentDrivenInteractiveTransition()
            if viewControllers.count > 1 {
                popViewController(animated: true)
            } else {
                dismiss(animated: true)
            }
        } else if gesture.state == .changed {
            interactionController?.update(percent)
        } else if gesture.state == .ended {
            if percent > 0.5 && gesture.state != .cancelled {
                interactionController?.finish()
            } else {
                interactionController?.cancel()
            }
            interactionController = nil
        }
    }
}

// MARK: - UINavigationControllerDelegate
//
// Use this for custom transitions as you push/pop between the varIoUs child view controllers 
// of the navigation controller. If you don't need a custom animation there,you can comment this
// out.

extension CustomNavigationController: UINavigationControllerDelegate {

    func navigationController(_ navigationController: UINavigationController,animationControllerFor operation: UINavigationControllerOperation,from fromVC: UIViewController,to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        if operation == .push {
            return ForwardAnimator()
        } else if operation == .pop {
            return BackAnimator()
        }
        return nil
    }

    func navigationController(_ navigationController: UINavigationController,interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
        return interactionController
    }

}

// MARK: - UIViewControllerTransitioningDelegate
//
// This is needed for the animation when we initially present the navigation controller. 
// If you're only looking for custom animations as you push/pop between the child view
// controllers of the navigation controller,this is not needed. This is only for the 
// custom transition of the initial `present` and `dismiss` of the navigation controller 
// itself.

extension CustomNavigationController: UIViewControllerTransitioningDelegate {

    func animationController(forPresented presented: UIViewController,presenting: UIViewController,source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return ForwardAnimator()
    }

    func animationController(fordismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return BackAnimator()
    }

    func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
        return interactionController
    }

    func interactionControllerFordismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
        return interactionController
    }

    func presentationController(forPresented presented: UIViewController,presenting: UIViewController?,source: UIViewController) -> UIPresentationController? {
        return PresentationController(presentedViewController: presented,presenting: presenting)
    }

}

// When doing custom `present`/`dismiss` that overlays the entire
// screen,you generally want to remove the presenting view controller's
// view from the view hierarchy. This presentation controller
// subclass accomplishes that for us.

class PresentationController: UIPresentationController {
    override var shouldRemovePresentersView: Bool { return true }
}

// You can do whatever you want in the animation; I'm just fading

class ForwardAnimator : NSObject,UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }

    func animateTransition(using context: UIViewControllerContextTransitioning) {
        let toView = context.viewController(forKey: .to)!.view!

        context.containerView.addSubview(toView)

        toView.alpha = 0.0

        UIView.animate(withDuration: transitionDuration(using: context),animations: {
            toView.alpha = 1.0
        },completion: { finished in
            context.completeTransition(!context.transitionWasCancelled)
        })
    }

}

class BackAnimator : NSObject,UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }

    func animateTransition(using context: UIViewControllerContextTransitioning) {
        let toView   = context.viewController(forKey: .to)!.view!
        let fromView = context.viewController(forKey: .from)!.view!

        context.containerView.insertSubview(toView,belowSubview: fromView)

        UIView.animate(withDuration: transitionDuration(using: context),animations: {
            fromView.alpha = 0.0
        },completion: { finished in
            context.completeTransition(!context.transitionWasCancelled)
        })
    }
}

因此,我可以将故事板中我的导航控制器的基类更改为此自定义子类,现在根场景可以只显示导航控制器(没有特殊的准备(对于:))并且一切正常.

ios – 从不调用交互式代理方法的更多相关文章

  1. html5利用canvas实现颜色容差抠图功能

    这篇文章主要介绍了html5利用canvas实现颜色容差抠图功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. Canvas图片分割效果的实现

    这篇文章主要介绍了Canvas图片分割效果的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5 Canvas实现放大镜效果示例

    这篇文章主要介绍了HTML5 Canvas实现放大镜效果示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  4. Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)

    这篇文章主要介绍了Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. html5如何在Canvas中实现自定义路径动画示例

    本篇文章主要介绍了html5如何在Canvas中实现自定义路径动画示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  6. canvas实现圆形进度条动画的示例代码

    这篇文章主要介绍了canvas实现圆形进度条动画的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. 教你使用Canvas处理图片的方法

    本篇文章主要介绍了教你使用Canvas处理图片的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. 手把手教你实现一个canvas智绘画板的方法

    这篇文章主要介绍了手把手教你实现一个canvas智绘画板的方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  9. 使用canvas来完成线性渐变和径向渐变的功能的方法示例

    这篇文章主要介绍了使用canvas来完成线性渐变和径向渐变的功能的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  10. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部