2015-02-18 57 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) 
       }) 
      }) 
     } 
    } 
} 
相關問題