Подтвердить что ты не робот

ОтклонитьModalViewController с переходом: слева направо

Я использовал хороший метод для отклонения моего модального контроллера:

[self dismissModalViewControllerWithTransition:2];

который делает переход слайда слева направо, как и контроллер навигации, чтобы открыть представление.

Поскольку этот метод является непубличным методом, apple не примет его. Как я могу запрограммировать этот вид анимации в моем коде (слайд слева направо, чтобы отклонить модальное представление и сдвинуть справа налево, чтобы представить модальное представление)?

Заранее спасибо

4b9b3361

Ответ 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];
}

Спасибо, ребята!

Ответ 2

Попробуйте следующее:

Я предполагаю, что вы отклоняете контроллер вида 2 из контроллера представления 1. В контроллере 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];

Ответ 3

Этот класс Swift 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
            }
        }
    }
}