web-dev-qa-db-ja.com

UINavigationControllerを使用せずにSegueアニメーションを水平にする方法は?

UISplitViewControllerを使用し、MasterViewControllerDetailViewControllerを使用し、UINavigationControllersを使用していません。

現在、マスター->詳細のセグエアニメーション、によってトリガーされます

performSegueWithIdentifier("showDetail", sender: self)

下から上に表示されるDetailViewControllerで構成されます。

そのアニメーションを左向きに表示するにはどうすればよいですか?

11
Daniele B

最近、セグエの実行方法をより細かく制御する必要があったため、すべて異なる方向に遷移を実行するカスタムセグエクラスを作成しました。実装の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)

        }) 

    }

}
11
Armin

--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がある場合、これは機能しません。

4
Mr_Vlasov

ビューコントローラをUINavigationControllersに埋め込みます。

SplitViewControllerテンプレートごと: enter image description here

小さいデバイスでは、マスターのnavigationControllerを使用する必要があります。

さらに、この質問には ここここここ が回答されています

View Controllerプログラミングガイド の詳細:

ビューコントローラを画面に表示するには、コンテナビューコントローラに埋め込むか、表示するかの2つの方法があります。コンテナビューコントローラは、アプリの主要なナビゲーションを提供します…。

ストーリーボードでは、ナビゲーションコントローラーに何かを埋め込むことはそれほど難しくありません。埋め込むビューコントローラーをクリックし、[エディター]-> [埋め込み]-> [ナビゲーションコントローラー]をクリックします。

3
beyowulf

新しいViewControllerがモーダルに表示されているように聞こえます。 detailViewControllerをUINavigationControllerに埋め込み、新しいコントローラーを押すと、右から左にアニメーション化され、デフォルトで戻るボタンも表示されます。

3
mylogon

コンパクト幅の画面の場合、 "詳細を表示"セグエはモーダルセグエにフォールバックします=自動的に。したがって、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 )
        }
    }
}
}
1
wj2061