2016-06-03 6 views
0
действия

Main View Controller, который отображает первый ModalОтклонить набор контроллеров с пользовательскими анимаций из второго контроллера представления

@IBAction func button(sender: AnyObject) { 
    let sb = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) 
    if let vc = sb.instantiateViewControllerWithIdentifier("VC1") as? FirstViewController { 
     vc.modalPresentationStyle = .OverCurrentContext 
     vc.modalTransitionStyle = .CrossDissolve 
     presentViewController(vc, animated: true, completion: nil) 
    } 
} 

VC1 Это имеет пользовательскую анимацию для перехода на 2-й контроллер представления

@IBAction func go(sender: AnyObject) { 
    guard let vc = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("VC2") as? SecondViewController else {return} 
    vc.transitioningDelegate = transitionManager 
    vc.modalPresentationStyle = .CurrentContext 
    presentViewController(vc, animated: true, completion: nil) 
} 

VC2 - просто смещать называют

@IBAction func dismiss(sender: AnyObject) { 
    dismissViewControllerAnimated(true, completion: nil) 
} 

VC2 является тот, который не работает. В настоящее время он отклоняется от VC1. Я бы хотел, чтобы он вернулся в Main, не возвращаясь первым.

Переход менеджер

class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate { 

// TRANSITION PROTOCOL METHODS 
func animateTransition(transitionContext: UIViewControllerContextTransitioning) { 
    guard let container = transitionContext.containerView() else {return} 
    guard let toView = transitionContext.viewForKey(UITransitionContextToViewKey) else {return} 
    guard let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey) else {return} 

    // set up from 2D transforms that we'll use in the animation 
    let width = container.frame.width 
    let offScreenRight = CGAffineTransformMakeTranslation(width, 0) 
    let offScreenLeft = CGAffineTransformMakeTranslation(-width, 0) 

    toView.transform = offScreenRight 

    container.addSubview(toView) 
    container.addSubview(fromView) 

    let duration = self.transitionDuration(transitionContext) 



    UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: .AllowAnimatedContent, animations: { 
     fromView.transform = offScreenLeft 
     toView.transform = CGAffineTransformIdentity 
    }) { finished in 
     transitionContext.completeTransition(true) 
    } 
} 

func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { 
    return 1.4 
} 


// DELEGATE METHODS 
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
    return self 
} 

func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
    return self 
} 

} 

Я попытался положить его в контроллер нав, отклоняя через self.presentingViewController.dismissViewcontroller, и куча других вещей. Я чувствую, что мне не хватает чего-то очень фундаментального в отношении контроллеров View, которые будут широко раскрыты.

Gif, как он не должен работать:

now not

Я хотел бы 2, чтобы вернуться домой, не видя 1 раз

EDIT: Я получил это на работу :

presentingViewController .presentingViewController .dismissViewControllerAnimated? (ложь, завершение: ноль)

Но это не кажется правильным и не выглядит правильным. Основная причина, по которой я занимаюсь этим стилем, состоит в том, что модалы в реальном проекте имеют полупрозрачные фоны, поэтому обычный навигационный контроллер или обычный переход заставляют их перекрываться уродливыми способами.

Это также односторонний уличный вид. VC1 не следует видеть после представления VC2, поэтому, возможно, я просто думаю об этом совершенно неправильно, а другой компонент стиля - лучший.

ответ

0

ли это получить:

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

редактировать: представление, а не родитель

+0

Это не так. У меня есть это, чтобы работать ... но это грубо и чувствует себя грязным. presentingViewController? .presentingViewController? .dismissViewControllerAnimated (false, completion: noil) –

+0

Несомненно, просто убедился, что это то, что было в стеке. Итак, вот что я сделал бы: wrap VC 1 в контроллере навигации. Основной VC _ представляет собой контроллер nav. Затем VC 1 _pushes_ VC 2 on. Теперь VC 2 может получить обратную ссылку на контроллер навигации с self.presentingViewController –

+0

Вправо. Когда я это сделал, я потерял свой переход. Навигационные переходы действительно не работают, потому что VC1 и VC2 являются полупрозрачными в проекте, и когда они перекрываются с помощью навигационного нажатия, это выглядит очень плохо. Может быть, я что-то упустил? Есть ли какая-то «толчок этой страницы полностью с той же скоростью, что и другая?» –

0

Это обычно делается с делегацией.

Создание протокола:

protocol ModalStackDismiss: class { 
    func dismissToModalRoot() 
} 

возвещать MainViewController в соответствии с ним.

class MainViewController: UIViewController,ModalStackDismiss 

ли MainViewController реализовать ModalStackDismiss «ы функция:

func dismissToModalRoot() 
{ 
     self.dismissViewControllerAnimated(true, completion: nil) 
} 

Для каждого контроллера представления, представленный модально создать делегат

weak var delegate:ModalStackDismiss? 

Затем передать ссылку делегата на каждый новый контроллер представления, представленном, например:

@IBAction func go(sender: AnyObject) { 
     guard let vc = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("VC2") as? SecondViewController else {return} 
     vc.transitioningDelegate = transitionManager 
     vc.modalPresentationStyle = .CurrentContext 
     vc.delegate = self.delegate // when presenting first vc from MainViewController should be vc.delegate = self 

     presentViewController(vc, animated: true, completion: nil) 
    } 

В любое время вы хотите, чтобы бежать в MainViewController:

@IBAction func dismiss(sender: AnyObject) { 
     if let modalDismissDelegate = self.delegate{ 
      modalDismissDelegate.dismissToModalRoot() 
     } 
    } 

Это совсем немного работы и, возможно, поэтому многие пытаются найти способы избежать делегирования, используя такие вещи, как self.presentingViewController? Другим вариантом было бы использовать NSNotificationCenter , Но исторически яблоко рекомендовало использовать протоколы и делегирование для отправки такого рода родительского и дочернего сообщений.

Смежные вопросы

 Смежные вопросы