[Swift]Segueを使って複数の画面に値渡しをする
こんにちは、プログラマーの@Yuuです。
前回の記事([Swift]初心者向け!Segueを使った画面遷移方法)で、Segueを使った画面遷移の方法をご紹介しました。
今回はSegueを使って画面遷移をする際に、値を次の画面に受け渡す方法をご紹介します。
また、遷移先が複数の画面である事を想定して説明します。
スポンサーリンク
Segueを使った画面間の値渡し
SecondとThirdがあるのに、Firstがないのは気にしない方向で・・
( ºωº )
この記事でのゴールは1番最初のViewControllerに変数を2つ用意し、その値をSecondViewControllerとThirdViewControllerそれぞれに渡してUILabelに表示する、というのを目標にします。
変数a・変数bていうネーミングセンスのなさも気にしない方向で・・
( ºωº )
今回は以下の4つの順番で解説を行います。
- UIViewControllerの用意
- それぞれのViewControllerにオブジェクトを配置
- Segueの設定
- 値を受け渡す
最初の「UIVewiControllerを用意する」ところは前回の説明と被るところもあるので簡略化して書きます。
分からないところがあれば前回の記事を参照するようお願いします。
また解説を行う環境は以下のとおりです。
- OS:OS X El Capitan10.11.5
- Xcode:7.3.1
- Swift:2.2
1. UIViewControllerの用意
前回と同じようにSingleApplicationで作成します。
次に「SecondViewController.swift」と「ThirdViewController.swift」を作成します。
Main.storyboardにUIViewControllerを2つ配置し、それぞれのクラスを「SecondViewController」・「ThirdViewController」にします。
この後は画面遷移を行うためのボタンや遷移先画面のラベルなどを配置していきます。
2. それぞれのViewControllerにオブジェクトを配置
まずはViewControllerにボタンを2つ配置します。
次にSecondViewControllerにLabelを2つと戻るボタンを配置します。
僕はThirdViewControllerと区別がつきやすいように背景色を変更しましたが、そこはお好みで。
真ん中に配置した「変数 aを表示」と書かれたラベルに、ViewControllerから受け取った値を表示するようにします。
同じようにThirdViewControllerにもLabelを2つと戻るボタンを配置します。
これでオブジェクトの配置は完了!
次はSegueの設定を行います。
3. Segueの設定
ViewControllerに配置した「Secondへ」というボタンからは「SecondViewController」へのSegueを、「Thirdへ」というボタンからは「ThirdViewController」へのSegueを設定します。
次にSegueに対して「Identifier」を設定します。
この「Identifier」の設定が今回の記事の中で2番目ぐらいに重要なところです。
「Identifier」の設定を忘れると値を渡す事が出来なくなるので注意して下さい。
ちなみに1番重要な項目はちゃんと後で出てきます、はい。
まずstoryboard上のViewControllerからSecondViewControllerに伸びるSegueを選択します。
すると以下のような「Identifier」を設定する画面がサイドバーに表示されます。
サイドバーが表示されない場合は「Hide or show the Utilities」というボタンを押してサイドバーをアクティブにして下さい。
「Identifier」の欄に「goSecond」と入力します。
同じようにViewControllerからThirdViewControllerに伸びるSegueのIdentifierに「goThird」と設定します。
これでSegueの設定は終了。
Segueの設定が終わったので、次はUnwind Segueの設定を行います。
ViewController.swiftを開きUnwind Segueの1文を追記します。
1 |
@IBAction func returnToTop(segue: UIStoryboardSegue) {} |
storyboardに戻ってSecondViewControllerとThirdViewControllerの「戻るボタン」にUnwind Segueを設定します。
Unwind Segueの設定方法など細かい解説は、前回([Swift]初心者向け!Segueを使った画面遷移方法)の記事に書いたので分からければ見て下さい。
Unwind Segueの設定が正常に出来ると、以下のようにstoryboardで「戻るボタン」にUnwind Segueが設定された事を確認出来ます。
これでSegueの設定は完了です!
ここまで出来ると以下のように一応遷移だけは出来る状態になっているはずです。
後はコード上に値を受け渡す設定を書いていきましょう。
4. 値を受け渡す
お待たせしました。
実際に値渡しの設定を書く、今回の記事で1番重要な部分について書いていきます!
画面遷移時の値の受け渡しの流れをViewControllerとSecondViewControllerを例にとって説明します。
ViewControllerの「Secondへ」ボタンが押される
↓
遷移先のSecondViewControllerをインスタンス化
↓
インスタンス化したSecondViewControllerの変数a
に、ViewControllerの変数a
を渡す
↓
インスタンス化したSecondViewControllerに遷移し変数a
の値を表示する
以上の流れをこれから書いていきます。
これは言葉での解説を読むよりコードを実際に書いた方が分かりやすいかも・・
ということで早速書いてみます!
ViewController.swiftに変数a・b
を用意します。
1 2 3 4 5 6 7 8 |
class ViewController: UIViewController { // 遷移先に渡す変数 let a = "ラーメン" let b = "うどん" ・・省略・・ } |
なぜ変数の値が「ラーメン」と「うどん」かは突っ込まない方向で・・
( ºωº )
SecondViewController.swiftに変数a
と、変数a
の値を表示するためのLabelを@IBOutlet
で用意します。
そしてViewDidLoad
メソッド内で変数a
の値をLabelに表示するように設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class SecondViewController: UIViewController { /// ViewControllerから受け取るための変数 var a = "" /// 変数aを表示するためのラベル @IBOutlet weak var aLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ラベルに受け取った値を表示 aLabel.text = a } ・・省略・・ } |
SecondViewController.swiftに用意したaLabel
は、アシスタントエディターに切り替えてstoryboard上のラベルと紐付けて下さい。
きちんと設定出来れば、storyboard上でラベルを選択するとSecondViewControllerの変数と紐付いている事が確認出来ます。
同様にThirdViewController.swiftにも変数b
と変数b
の値を表示するLabelを用意し、表示するための設定を書きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import UIKit class ThirdViewController: UIViewController { /// ViewControllerから受け取るための変数 var b = "" /// 変数bを表示するためのラベル @IBOutlet weak var bLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ラベルに受け取った値を表示 bLabel.text = b } ・・省略・・ } |
最後にViewController.swiftに遷移をする際に値を渡す記述をします。
Segueを使って画面遷移を行う際にはprepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
というメソッドが必ず呼ばれます。
このメソッドをoverrideしてデータを受け渡す設定を書きます。
またSegueで画面遷移時に必ず呼ばれるメソッドなので、SecondViewController・ThirdViewControllerどちらでも同じく、このprepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
メソッドが呼ばれます。
そのため、SecondViewController・ThirdViewControllerどちらに遷移したいのか判定し、その上で値の受け渡しをしないといけません。
その際に先程Segueに指定したIdentifierを使用します。
Identifierで遷移先を判定するprepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
メソッドをViewController.swiftに追記して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/// Segueで遷移する際のメソッド override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "goSecond" { //SecondViewControllerに遷移する場合 // SecondViewControllerをインスタンス化 let secondVc = segue.destinationViewController as! SecondViewController // 値を渡す secondVc.a = self.a }else if segue.identifier == "goThird" { //ThirdViewControllerに遷移する場合 // ThirdViewControllerをインスタンス化 let thirdVc = segue.destinationViewController as! ThirdViewController // 値を渡す thirdVc.b = self.b }else { // どちらでもない遷移 } } |
これでデータを渡せるようになったはず。
実際に試してみると
無事データを渡せるようになりました!
(๑•̀ㅂ•́)و✧
今回のプロジェクトはgithubに上げておいたので、よければ参考にしてみて下さい。
meganedogYuu/DeliveryValueSegueSample: Segueを使って複数のVCに値渡しを行うサンプル
最後にViewController.swift・SecondViewController.swift・ThirdViewController.swiftの全文を載せておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import UIKit class ViewController: UIViewController { // 遷移先に渡す変数 let a = "ラーメン" let b = "うどん" override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } /// Segueで遷移する際のメソッド override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "goSecond" { //SecondViewControllerに遷移する場合 // SecondViewControllerをインスタンス化 let secondVc = segue.destinationViewController as! SecondViewController // 値を渡す secondVc.a = self.a }else if segue.identifier == "goThird" { //ThirdViewControllerに遷移する場合 // ThirdViewControllerをインスタンス化 let thirdVc = segue.destinationViewController as! ThirdViewController // 値を渡す thirdVc.b = self.b }else { // どちらでもない遷移 } } /// この画面に戻ってくるようにするUnwind Segue @IBAction func returnToTop(segue: UIStoryboardSegue) {} } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import UIKit class SecondViewController: UIViewController { /// ViewControllerから受け取るための変数 var a = "" /// 変数aを表示するためのラベル @IBOutlet weak var aLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ラベルに受け取った値を表示 aLabel.text = a } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import UIKit class ThirdViewController: UIViewController { /// ViewControllerから受け取るための変数 var b = "" /// 変数bを表示するためのラベル @IBOutlet weak var bLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // ラベルに受け取った値を表示 bLabel.text = b } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
あとがき
Segueを設定するのは簡単ですが、値を受け渡すのは意外とめんどくさいですね。
Segueを設定するのと同じぐらいに値渡しが簡単に出来たらいいのに・・
ではでは
今回はこの辺で!ヽ(•̀ω•́ )ゝ✧