2015-02-18 66 views
1

我有一个Storyboard设置,并且在某个时候一个按钮用另一个按钮替换了细节视图。默认情况下,根本没有转换:视图控制器突然被替换。我可以创建一个吗?动画替换UISplitViewController中的细节视图

我的猜测是使用自定义转换 - 就像您通常为视图更改具有自定义动画一样 - 但我不知道如何实现分割视图控制器的“替换”行为。

回答

1

我做了这个使用自定义segue,当有splitViewController,我做“显示细节”,否则我尝试推/呈现模态。所有动画。该节目模式的动画会褪色的旧控制器出与改造,并显示新的与将变更

class ShowDetailSegue: UIStoryboardSegue { 

    private let showFromScale : CGFloat = 0.8 
    private let hideToScale : CGFloat = 1.2 
    private let animationDuration : NSTimeInterval = 0.33 

    override func perform() { 

     let sourceVC = self.sourceViewController as! UIViewController 
     let destinationVC = self.destinationViewController as! UIViewController 
     let animated = true 

     if let splitVC = sourceVC.splitViewController where splitVC.isInSplitView { 
      // splitview with detail is visible, we will show detail with animation 
      showDetail(splitVC, sourceVC : sourceVC, destinationVC: destinationVC, animated: animated) 
     } else if let navController = sourceVC.navigationController { 
      // there is no split view – just push to navigation controller 
      sourceVC.navigationController?.pushViewController(destinationVC, animated: animated) 
     } else { 
      // no navigation found, let just present modal 
      sourceVC.presentViewController(destinationVC, animated: animated, completion: nil) 
     } 

    } 

    private func showDetail(splitVC : UISplitViewController, sourceVC : UIViewController, destinationVC : UIViewController, animated : Bool) { 

     let newDetailVC = GeneralNavigationController(rootViewController: destinationVC) 
     newDetailVC.applyAppearance() 

     if !animated { 

      splitVC.showDetailViewController(newDetailVC, sender: sourceVC) 

     } else { 

      var currentDetailVC = splitVC.viewControllers.last as! UIViewController 

      if let currentDetailNC = currentDetailVC as? UINavigationController { 
       currentDetailVC = currentDetailNC.topViewController 
      } 

      UIView.animateWithDuration(animationDuration/2.0, animations: {() -> Void in 
       // hide the old view with transform 

       currentDetailVC.view.alpha = 0 
       currentDetailVC.view.transform = CGAffineTransformMakeScale(self.hideToScale, self.hideToScale) 
       currentDetailVC.navigationController?.navigationBar.alpha = 0 

       }, completion: { (completed) -> Void in 

        newDetailVC.navigationController?.navigationBar.alpha = 0 
        newDetailVC.view.alpha = 0 
        newDetailVC.view.transform = CGAffineTransformScale(newDetailVC.view.transform, self.showFromScale, self.showFromScale) 

        splitVC.showDetailViewController(newDetailVC, sender: sourceVC) 

        // Show new view 

        UIView.animateWithDuration(self.animationDuration/2.0, animations: {() -> Void in 

         newDetailVC.view.alpha = 1 
         newDetailVC.view.transform = CGAffineTransformScale(newDetailVC.view.transform, 1/self.showFromScale, 1/self.showFromScale) 

         newDetailVC.navigationController?.navigationBar.alpha = 1 

         }, completion: { (completed) -> Void in 

          currentDetailVC.view.transform = CGAffineTransformScale(currentDetailVC.view.transform, 1/self.hideToScale, 1/self.hideToScale) 
        }) 
      }) 


     } 


    } 

} 
0

我用Pavel Smejkal's answer,具有以下装饰:

  • 新的细节控制器可能已经被嵌入在 UINavigationController的,所以我检查为
  • 我拿出引用他的习惯 导航控制器类
  • 我将它转换ŧ ø夫特3

这里是修改后的代码:

import UIKit 

class SegueShowDetail: UIStoryboardSegue { 

    private let showFromScale: CGFloat = 0.8 
    private let hideToScale: CGFloat = 1.2 
    private let animationDuration: TimeInterval = 0.33 

    override func perform() { 

     let sourceVC = self.source 
     let destinationVC = self.destination 
     let animated = true 

     if let splitVC = sourceVC.splitViewController, !splitVC.isCollapsed { 

      // splitview with detail is visible, we will show detail with animation 
      showDetail(splitVC: splitVC, sourceVC : sourceVC, destinationVC: destinationVC, animated: animated) 

     } else if let navController = sourceVC.navigationController { 

      // there is no split view – just push to navigation controller 
      sourceVC.navigationController?.pushViewController(destinationVC, animated: animated) 

     } else { 
      // no navigation found, let just present modal 
      sourceVC.present(destinationVC, animated: animated, completion: nil) 
     } 

    } 

    fileprivate func showDetail(splitVC : UISplitViewController, sourceVC : UIViewController, destinationVC : UIViewController, animated : Bool) { 

     var navController: UINavigationController? = destinationVC as? UINavigationController 
     if nil == navController { 

      navController = UINavigationController(rootViewController: destinationVC) 
     } 

     guard let newDetailNavVC = navController else { 

      return 
     } 

     if !animated { 

      splitVC.showDetailViewController(newDetailNavVC, sender: sourceVC) 

     } else { 

      var currentDetailVC = splitVC.viewControllers.last! 

      if let currentDetailNC = currentDetailVC as? UINavigationController { 
       currentDetailVC = currentDetailNC.topViewController! 
      } 

      UIView.animate(withDuration: animationDuration/2.0, animations: {() -> Void in 
       // hide the old view with transform 

       currentDetailVC.view.alpha = 0 
       currentDetailVC.view.transform = CGAffineTransform(scaleX: self.hideToScale, y: self.hideToScale) 
       currentDetailVC.navigationController?.navigationBar.alpha = 0 

      }, completion: { (completed) -> Void in 

       newDetailNavVC.navigationController?.navigationBar.alpha = 0 
       newDetailNavVC.view.alpha = 0 
       newDetailNavVC.view.transform = newDetailNavVC.view.transform.scaledBy(x: self.showFromScale, y: self.showFromScale) 

       splitVC.showDetailViewController(newDetailNavVC, sender: sourceVC) 

       // Show new view 

       UIView.animate(withDuration: self.animationDuration/2.0, animations: {() -> Void in 

        newDetailNavVC.view.alpha = 1 
        newDetailNavVC.view.transform = newDetailNavVC.view.transform.scaledBy(x: 1/self.showFromScale, y: 1/self.showFromScale) 

        newDetailNavVC.navigationController?.navigationBar.alpha = 1 

       }, completion: { (completed) -> Void in 

        currentDetailVC.view.transform = currentDetailVC.view.transform.scaledBy(x: 1/self.hideToScale, y: 1/self.hideToScale) 
       }) 
      }) 
     } 
    } 
} 
相关问题