dismissModalViewController过渡:从左到右(dismissModalView

2019-06-26 04:11发布

我用一个很好的方法来打发我的模态视图控制器:

[self dismissModalViewControllerWithTransition:2];

这使得滑动过渡从左至右,像导航控制器确实弹出的图。

由于这种方法是一种非公开的方式,苹果是不会接受的。 我怎么能在我的代码这种动画方案(从左至右滑动,驳回模式的看法,并从右侧滑动至左侧呈现模态的视图)?

提前致谢

Answer 1:

我已经接受了Safecase的答案,但我想在这里发布我的最终解决方案:

1)由右至我已经写以下方法左过渡与呈现模态的视图控制器:

-(void) presentModalView:(UIViewController *)controller {
    CATransition *transition = [CATransition animation];
    transition.duration = 0.35;
    transition.timingFunction =
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionMoveIn;
    transition.subtype = kCATransitionFromRight;

    // NSLog(@"%s: self.view.window=%@", _func_, self.view.window);
    UIView *containerView = self.view.window;
    [containerView.layer addAnimation:transition forKey:nil];
    [self presentModalViewController:controller animated:NO];
}

2)要关闭左向右的幻灯片过渡模态的视图:

-(void) dismissMe {
    CATransition *transition = [CATransition animation];
    transition.duration = 0.35;
    transition.timingFunction =
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionMoveIn;
    transition.subtype = kCATransitionFromLeft;

    // NSLog(@"%s: controller.view.window=%@", _func_, controller.view.window);
    UIView *containerView = self.view.window;
    [containerView.layer addAnimation:transition forKey:nil];

    [self dismissModalViewControllerAnimated:NO];
}

多谢你们!



Answer 2:

试试这个:

我asume要从视图控制器1驳回视图控制器2在视图控制器2使用的是此

[self  dismissModalViewControlleAnimated: NO]];

现在在第一视图控制器,在viewWillAppear中:方法添加代码

CATransition *animation = [CATransition animation];

[animation setDelegate:self];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];

[animation setDuration:0.50];
[animation setTimingFunction:
 [CAMediaTimingFunction functionWithName:
  kCAMediaTimingFunctionEaseInEaseOut]];


[self.view.layer addAnimation:animation forKey:kCATransition];


Answer 3:

这斯威夫特4 ModalService下面类是预包装的灵活解决方案,可以被放入一个项目,并呼吁从任何地方它是必需的。 此类带来的模态的视图中对从指定的方向上的当前视图的顶部,并且然后移动出来以显示它后面的原始视图退出时。 给定一个presentingViewController当前正在显示和modalViewController您已经创建并希望显示,您只需拨打:

ModalService.present(modalViewController, presenter: presentingViewController)

然后,辞退,拨打:

ModalService.dismiss(modalViewController)

当然,这可以从modalViewController本身作为被称为ModalService.dismiss(self) 。 需要注意的是解聘不必从presentingViewController调用,并且不需要知识或使原有的presentingViewController的参考。

该类提供合理的默认值,包括从右侧和流出向左过渡模态视图。 这种过渡方向可以通过传递的方向,其可被定制为两个入口和出口进行定制:

ModalService.present(modalViewController, presenter: presentingViewController, enterFrom: .left)

ModalService.dismiss(self, exitTo: .left)

这可以被设置为.left.right.top.bottom 。 同样,可以通过自定义的持续时间以秒,如果你想:

ModalService.present(modalViewController, presenter: presentingViewController, enterFrom: .left, duration: 0.5)

ModalService.dismiss(self, exitTo: .left, duration: 2.0)

头点头@jcdmb对这个问题进行其形成在这一类解决方案的内核Objective C的答案。


下面是完整的类。 私营返回的值transitionSubtype看起来很奇怪,但故意这样设置。 假设这些需要“纠正”之前,您应该测试所观察到的行为。 :)

import UIKit

class ModalService {

    enum presentationDirection {
        case left
        case right
        case top
        case bottom
    }

    class func present(_ modalViewController: UIViewController,
                       presenter fromViewController: UIViewController,
                       enterFrom direction: presentationDirection = .right,
                       duration: CFTimeInterval = 0.3) {
        let transition = CATransition()
        transition.duration = duration
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionMoveIn
        transition.subtype = ModalService.transitionSubtype(for: direction)
        let containerView: UIView? = fromViewController.view.window
        containerView?.layer.add(transition, forKey: nil)
        fromViewController.present(modalViewController, animated: false)
    }

    class func dismiss(_ modalViewController: UIViewController,
                       exitTo direction: presentationDirection = .right,
                       duration: CFTimeInterval = 0.3) {
        let transition = CATransition()
        transition.duration = duration
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionReveal
        transition.subtype = ModalService.transitionSubtype(for: direction, forExit: true)
        if let layer = modalViewController.view?.window?.layer {
            layer.add(transition, forKey: nil)
        }
        modalViewController.dismiss(animated: false)
    }

    private class func transitionSubtype(for direction: presentationDirection, forExit: Bool = false) -> String {
        if (forExit == false) {
            switch direction {
            case .left:
                return kCATransitionFromLeft
            case .right:
                return kCATransitionFromRight
            case .top:
                return kCATransitionFromBottom
            case .bottom:
                return kCATransitionFromTop
            }
        } else {
            switch direction {
            case .left:
                return kCATransitionFromRight
            case .right:
                return kCATransitionFromLeft
            case .top:
                return kCATransitionFromTop
            case .bottom:
                return kCATransitionFromBottom
            }
        }
    }
}


文章来源: dismissModalViewController with transition: left to right