2016-01-11 5 views
0

Я пытаюсь обеспечить общую реализацию UIViewControllerAnimatedTransitioning с помощью Swift протоколов, но всякий раз, когда у меня есть объект, который соответствует протоколу, я получаю ошибку:вина Сегментация при расширении UIViewControllerAnimatedTransitioning

Command failed due to signal: Segmentation fault: 11 

Когда генерики удаляются, я все еще получаю проблему.

Вот мой протокол, с дженерики закомментирована:

protocol TransitionControllerType: UIViewControllerAnimatedTransitioning { 
// typealias PresentingViewController: UIViewController 
// typealias PresentedViewController: UIViewController 

    var isPresentation: Bool { get set } 
    var presentationTransitionDuration: NSTimeInterval { get } 
    var dismissTransitionDuration: NSTimeInterval { get } 

    func prepareViewControllerForPresentation(viewController: UIViewController, presentingViewController: UIViewController) 
    func presentViewController(viewController: UIViewController, presentingViewController: UIViewController) 
    func dismissViewController(viewController: UIViewController, presentingViewController: UIViewController) 
} 

PresentingViewController и PresentedViewController бы просто вместо UIViewController в prepareViewController(::), presentViewController(::) и dismissViewController(::).

Я обеспечить реализацию UIViewControllerAnimatedTransitioning в расширении для TransitionControllerType:

extension TransitionControllerType { 
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { 
     return isPresentation ? presentationTransitionDuration : dismissTransitionDuration 
    } 

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) { 
     // Ensure there is a container view 
     guard let containerView = transitionContext.containerView() else { 
      return 
     } 

     // Get the view controllers 
     let (fromViewController, toViewController) = transitionContext.viewControllers() 

//  // Cast the view controllers 
//  guard let presentedViewController = (isPresentation ? toViewController : fromViewController) as? PresentedViewController, 
//   let presentingViewController = (isPresentation ? fromViewController : toViewController) as? PresentingViewController 
//  else { 
//   return 
//  } 
     guard let presentedViewController = (isPresentation ? toViewController : fromViewController), 
      let presentingViewController = (isPresentation ? fromViewController : toViewController) 
     else { 
      return 
     } 

     // Get the views from the view controllers 
     let presentedView = presentedViewController.view 
     let presentingView = presentingViewController.view 

     // If it's a presentation, prepare the view controllers 
     if isPresentation { 
      prepareViewControllerForPresentation(presentedViewController, presentingViewController: presentingViewController) 
      containerView.addSubview(presentedView) 
     } 

     UIView.animateWithDuration(
      transitionDuration(transitionContext), 
      delay: 0, 
      usingSpringWithDamping: isPresentation ? PresentationSpringDamping : DismissSpringDamping, 
      initialSpringVelocity: isPresentation ? PresentationSpringVelocity : DismissSpringVelocity, 
      options: isPresentation ? UIViewAnimationOptions.CurveEaseOut : [], 
      animations: { 
       if self.isPresentation { 
        self.presentViewController(presentedViewController, presentingViewController: presentingViewController) 
       } else { 
        self.dismissViewController(presentedViewController, presentingViewController: presentingViewController) 
       } 
      }, 
      completion: { success in 
       transitionContext.completeTransition(success) 

       // !!!: We have to manually add `presentationView` due to a bug 
       // http://openradar.appspot.com/radar?id=5320103646199808 
       if !self.isPresentation { 
        UIApplication.sharedApplication().keyWindow?.addSubview(presentingView) 
       } else { 
        UIApplication.sharedApplication().keyWindow?.addSubview(presentedView) 
       } 
     }) 
    } 


    func prepareViewControllerForPresentation(viewController: UIViewController, presentingViewController: UIViewController) { } 
    func presentViewController(viewController: UIViewController, presentingViewController: UIViewController) { } 
    func dismissViewController(viewController: UIViewController, presentingViewController: UIViewController) { } 
} 

Попытка запустить проект на данном этапе приведет к успешной сборки.

Если я попытаюсь реализовать протокол на NSObject (для соответствия UIViewControllerAnimatedTransitioning), я получаю ошибку ошибки сегментации.

Ниже класс, который я использую для transitioningDelegate при представлении AddNewMenuViewController и TransitionControllerType используется

class AddNewMenuTransitionControllerDelegate: NSObject, UIViewControllerTransitioningDelegate { 
    func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController? { 
     return AddNewMenuPresentationController(presentedViewController: presented, presentingViewController: presenting, blurStyle: .Dark) 
    } 

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

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

class AddNewMenuTransitionController: NSObject, TransitionControllerType { 
    var isPresentation: Bool 
    var presentationTransitionDuration: NSTimeInterval = 0.3 
    var dismissTransitionDuration: NSTimeInterval = 0.3 

    init(presentation: Bool = false) { 
     self.isPresentation = presentation 

     super.init() 
    } 
} 

Почему необщего версии результат в той же самой ошибки сегментации как дженерика?

ответ

0

Я не думаю, что компилятор распознает реализацию методы по умолчанию в animateTransition добавленного расширения к протоколу TransitionControllerType при попытке выяснить, если ваш класс AddNewMenuTransitionController удовлетворяет протокол UIViewControllerAnimatedTransitioning (который требуется ваша декларация TransitionControllerType).

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

Это может работать (но я не пробовал), если вы не требуете UIViewControllerAnimatedTransitioning в определении TransitionControllerType, но вместо этого добавьте его явно в определение класса.

Я уверен, что это не так чисто, как то, к чему вы стремились, но косвенная реализация метода с использованием промежуточного протокола, по-видимому, слишком много для компилятора в это время.

+0

Я удалил соответствие с 'UIVIewControllerAnimatedTransitioning' из' TransitionControllerType' и добавил его в мой 'AddNewMenuTransitionController'. К сожалению, все еще существует ошибка seg. Любые другие идеи? – HighFlyingFantasy

+0

Я также пытался добавить 'расширение UIViewControllerAnimatedTransitioning, где Self: TransitionControllerType', но все методы должны быть помечены' @ objc', но вы не можете пометить методы '@ objc' в расширении – HighFlyingFantasy

+0

Я не знаю, протокол требуется какой-то другой частью вашего приложения, но вы всегда можете сделать TransitionControllerType производным классом NSObject и вывести из него AddNewMenuTransitionController вместо NSObject (и вообще отказаться от протокола) –

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