徒然Swiftメモ（画面遷移編）

SwiftでiPhoneアプリを作成する際に知ったちょっとしたことを
徒然なるままに書いていく。

***※勉強用にメモしたものです。***

# Navigation Controllerの追加

storyboard画面で、「Editor」 -> 「Embed In」 -> 「Navigation Controller」を選択する

# storyboardを操作する

## swiftのコード内でstoryboardのインスタンスを取得

```swift

var storyboard: UIStoryboard = UIStoryboard(name: // storyboardの名前 //, bundle: NSBundle.mainBundle())

```

* NSBundle.mainBundle()  
プロジェクトのパスを取得するメソッド。

## storyboardのinitial view controller を取得

```swift
storyboard.instantiateInitialViewController()
```

* 「as!」または「as?」を使ってキャストする必要あり

## storyboardの任意のビューコントローラのインスタンス取得

```swift

storyboard.instantiateViewControllerWithIdentifier(// コントローラのIdentifier //);

```

* IdentifierはstoryboardでセットするコントローラのID

# ボタンクリックで画面遷移 (segue)

segueを使うと画面遷移がGUIで作成できる（超便利）  

セグエの設定方法はstoryboardでボタンから遷移先のビューコントローラへ「control」を押しながらドラッグするだけ

![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/51071/9e59c54d-03f6-0742-76af-b280275f3e28.png)

画面遷移時に，「prepareForSegue」が呼び出されるのでこの関数で画面遷移時の操作を書けばパラメータを渡したりできる。

引数「segue」の「destinationViewController」を使ってビューコントローラを呼び出し，メソッドにパラメータを渡すなりすれば次のページに値を渡すこともできる！

引数「segue」の「identifier」でセグエのIDが取得できる。この引数を使うことで複数のセグエを切り替えて使用することができる
 
```swift
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        var vc: SecondPageViewController = segue.destinationViewController as! SecondPageViewController  // 遷移先のビューコントローラを取得できる。
    if(segue.identifier != nil) {
        println(segue.identifier!); // セグエのIDが表示される
    }
}
```

# ボタンクリックで画面遷移 (presentViewController)

「presentViewController」を使えば，セグエを使わないで画面遷移可能。

## 次の画面表示
```swift

self.presentViewController(// 遷移先のビューコントローラ //, animated: true, completion: nil)

```

## 次の画面から前の画面に戻る

```swift
self.dismissViewControllerAnimated(true, completion: nil)
```

* 第１引数はアニメーションをするかしないかをtrue/falseで指定
* completionはクロージャ指定。まだよくわかっていない

## 画面遷移のアニメーション指定

```swift
vs.modalTransitionStyle = UIModalTransitionStyle.FlipHorizontal
self.presentViewController(vs, animated: true, completion: nil)
```

* 変数「vs」はUIViewControllerのインスタンス
* UIModalTransitionStyleで指定できるアニメーションは幾つかある
    + CoverVertical => 下から画面が出てくる感じのやつ
    + FlipHorizontal => トランプをめくるような感じ
    + CrossDissolve => jQuery Mobileの画面遷移みたいなやつ。フェード？
    + PartialCurl => カレンダーをめくるようなアニメーション

### viewDidLoadで呼び出すとワーニング発生
self.presentViewControllerを使って画面遷移をする処理を「viewDidLoad」で呼び出したら**「Presenting view controllers on detached view controllers is discouraged」**というワーニングが発生した。 

調査したところ，次の方法で画面遷移すればワーニングが出なくなることは
確認したけどなぜこれでうまくいくのかは理解できていない

```swift
self.view.window?.rootViewController!.presentViewController(vs!, animated: animated, completion: completion)
```

# segueとpresentViewControllerの使い分け

下のような感じと思う

* segue  
シンプルな画面遷移の場合はsegueを使って実装したほうが楽
* presentViewController  
「状態によって遷移先が変わる」とか、
「別のstoryboardの画面に遷移する」場合など、複雑な画面遷移をする場合はこちらを使う

# 応用 -指定したstoryboardに画面遷移-

ボタンを押した時に別のstoryboardに画面遷移

```swift
    @IBAction func doTouchBtn(sender: AnyObject) {

        // storyboardのインスタンス取得
        var storyboard: UIStoryboard = UIStoryboard(name: "Modal1", bundle: NSBundle.mainBundle())
        // Modal1ViewController取得 ※ ModalViewControllerは自作のViewController
        var vs: Modal1ViewController = storyboard.instantiateInitialViewController() as! Modal1ViewController
        // アニメーション設定
        vs.modalTransitionStyle = UIModalTransitionStyle.PartialCurl
        // 画面遷移
        self.presentViewController(vs, animated: true, completion: nil)
    }

```