UISplitViewController
を使用し、MasterViewController
とDetailViewController
を使用し、UINavigationController
sを使用していません。
現在、マスター->詳細のセグエアニメーション、によってトリガーされます
performSegueWithIdentifier("showDetail", sender: self)
下から上に表示されるDetailViewController
で構成されます。
そのアニメーションを左向きに表示するにはどうすればよいですか?
最近、セグエの実行方法をより細かく制御する必要があったため、すべて異なる方向に遷移を実行するカスタムセグエクラスを作成しました。実装の1つは次のとおりです。
スイフト2.x
override func perform() {
//credits to http://www.appcoda.com/custom-segue-animations/
let firstClassView = self.sourceViewController.view
let secondClassView = self.destinationViewController.view
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
secondClassView.frame = CGRectMake(screenWidth, 0, screenWidth, screenHeight)
if let window = UIApplication.sharedApplication().keyWindow {
window.insertSubview(secondClassView, aboveSubview: firstClassView)
UIView.animateWithDuration(0.4, animations: { () -> Void in
firstClassView.frame = CGRectOffset(firstClassView.frame, -screenWidth, 0)
secondClassView.frame = CGRectOffset(secondClassView.frame, -screenWidth, 0)
}) {(Finished) -> Void in
self.sourceViewController.navigationController?.pushViewController(self.destinationViewController, animated: false)
}
}
}
これは「右から左」への遷移があります。ソースビューコントローラとデスティネーションビューコントローラの初期位置と終了位置を変更するだけで、必要に応じてこの関数を変更できます。
また、セグエを「カスタムセグエ」としてマークし、それに新しいクラスを割り当てる必要があることを忘れないでください。
PDATE:追加Swift 3バージョン
Swift
override func perform() {
//credits to http://www.appcoda.com/custom-segue-animations/
let firstClassView = self.source.view
let secondClassView = self.destination.view
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
secondClassView?.frame = CGRect(x: screenWidth, y: 0, width: screenWidth, height: screenHeight)
if let window = UIApplication.shared.keyWindow {
window.insertSubview(secondClassView!, aboveSubview: firstClassView!)
UIView.animate(withDuration: 0.4, animations: { () -> Void in
firstClassView?.frame = (firstClassView?.frame.offsetBy(dx: -screenWidth, dy: 0))!
secondClassView?.frame = (secondClassView?.frame.offsetBy(dx: -screenWidth, dy: 0))!
}, completion: {(Finished) -> Void in
self.source.navigationController?.pushViewController(self.destination, animated: false)
})
}
}
--Swift 3.-
Swift 3. New-> File-> Cocoa Touch Class-> Class:...(Subclass:UIStoryboardSegue)に適合したArminのソリューション。
import UIKit
class SlideHorSegue: UIStoryboardSegue {
override func perform() {
//credits to http://www.appcoda.com/custom-segue-animations/
let firstClassView = self.source.view
let secondClassView = self.destination.view
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
secondClassView?.frame = CGRect(x: screenWidth, y: 0, width: screenWidth, height: screenHeight)
if let window = UIApplication.shared.keyWindow {
window.insertSubview(secondClassView!, aboveSubview: firstClassView!)
UIView.animate(withDuration: 0.4, animations: { () -> Void in
firstClassView?.frame = (firstClassView?.frame)!.offsetBy(dx: -screenWidth, dy: 0)
secondClassView?.frame = (secondClassView?.frame)!.offsetBy(dx: -screenWidth, dy: 0)
}) {(Finished) -> Void in
self.source.navigationController?.pushViewController(self.destination, animated: false)
}
}
}
}
ストーリーボードで:セグエを「カスタムセグエ」としてマークし、それに新しいクラスを割り当てます。
注:detailesVCにUIScrollViewがある場合、これは機能しません。
ビューコントローラをUINavigationControllersに埋め込みます。
小さいデバイスでは、マスターのnavigationControllerを使用する必要があります。
さらに、この質問には ここ と ここ と ここ が回答されています
View Controllerプログラミングガイド の詳細:
ビューコントローラを画面に表示するには、コンテナビューコントローラに埋め込むか、表示するかの2つの方法があります。コンテナビューコントローラは、アプリの主要なナビゲーションを提供します…。
ストーリーボードでは、ナビゲーションコントローラーに何かを埋め込むことはそれほど難しくありません。埋め込むビューコントローラーをクリックし、[エディター]-> [埋め込み]-> [ナビゲーションコントローラー]をクリックします。
新しいViewControllerがモーダルに表示されているように聞こえます。 detailViewControllerをUINavigationController
に埋め込み、新しいコントローラーを押すと、右から左にアニメーション化され、デフォルトで戻るボタンも表示されます。
コンパクト幅の画面の場合、 "詳細を表示"セグエはモーダルセグエにフォールバックします=自動的に。したがって、DetailViewControllerはデフォルトのモーダルセグエとして垂直に表示されます。
UIViewControllerTransitioningDelegateを使用して、モーダルセグエのアニメーションをカスタマイズできます。
水平方向のアニメーションを実現する例を次に示します。
1。 transitioningDelegateとそのデリゲートメソッドを設定します
class MasterViewController: UITableViewController,UIViewControllerTransitioningDelegate {
//prepare for segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
let detailVC = segue.destinationViewController as! DetailViewController
detailVC.transitioningDelegate = self
// detailVC.detailItem = object//Configure detailVC
}
}
//UIViewControllerTransitioningDelegate
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return LeftTransition()
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let leftTransiton = LeftTransition()
leftTransiton.dismiss = true
return leftTransiton
}
}
2:カスタムUIViewControllerAnimatedTransitioning:LeftTransition
import UIKit
class LeftTransition: NSObject ,UIViewControllerAnimatedTransitioning {
var dismiss = false
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 2.0
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning){
// Get the two view controllers
let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
let containerView = transitionContext.containerView()!
var originRect = containerView.bounds
originRect.Origin = CGPointMake(CGRectGetWidth(originRect), 0)
containerView.addSubview(fromVC.view)
containerView.addSubview(toVC.view)
if dismiss{
containerView.bringSubviewToFront(fromVC.view)
UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in
fromVC.view.frame = originRect
}, completion: { (_ ) -> Void in
fromVC.view.removeFromSuperview()
transitionContext.completeTransition(true )
})
}else{
toVC.view.frame = originRect
UIView.animateWithDuration(transitionDuration(transitionContext),
animations: { () -> Void in
toVC.view.center = containerView.center
}) { (_) -> Void in
fromVC.view.removeFromSuperview()
transitionContext.completeTransition(true )
}
}
}
}