今回は、画面遷移(画面の切り替え)の方法をご紹介します。また、画面遷移で遷移先に値を渡す方法と条件が達成されると自動で画面遷移する方法も組み入れました。ご紹介する内容では、1つの値を渡していますが、値を渡せるようになると、tableViewを活用し、複数のデータを渡せるようになります。まずは、基本からということで、1つの値を渡せるようになりましょう。
完成形のイメージ
まず最初に、今回ご紹介するコードで出来上がった完成形を動画にしました。全コードは、ページの最後に載せています。
1. ストーリーボードにパーツを準備
始めに、画面遷移先の画面を作成します。右上の+ボタンからView Controllerを追加します。画面内のボタンや、2つのView Controller間の矢印のつながりは無視して下さい。後から、説明します。
追加した画面(下の図の右側のView Controller)には、名前が付いておらず、また対応したswiftファイルもありません。そこで、ファイルを作成します。
- TestSenyiフォルダで右クリック(今回使用したフォルダ名です)
- NewFile…を左クリック
- Cocoa Touch Classを選択し、Nextボタンを左クリック
- Class名にNextViewControllerと入力し、SubclassはUIViewController、Languageはswift、としNextボタンを左クリック
- さらにCreateボタンを左クリック
ファイルの作成ができたと思います。
次に、Controllerに名前を付けるため、右側のView Controllerの上の白いバーのところを左クリックすると、画面右にCustom Classが表示されます。ここのClassに作成したファイル名と同じ、NextViewControllerと入力して下さい。
次に、画面遷移の下準備をします。
左のView Controllerの上の白いバーにある一番左のアイコンのところから、Control+左クリックを押し、ドラッグで右のNextViewControllerに繋ぎます。そうすると、2つの画面の真ん中が矢印で繋がります。
繋がった矢印を左クリックし、右側に表示されたStoryboard Segueのidentifierにnextと入力します。これで、画面遷移の下準備は終了です。
次に、ViewControllerのパーツとコードを繋ぎます。
- 背景の緑
- UIimageViewを画面いっぱいに貼り付け、backgroundでcolorを変更しています。(ImageViewを選択すると、画面右に設定できる項目が並びます。その中にBackgrondがあります。)
- Labelを1つ追加
- カウントを表示するためのラベル。
- Buttonを3つ追加
- カウントアップボタン
- カウントダウンボタン
- 画面遷移ボタン
ストーリーボードとコードを繋ぐ際は、Control+左クリック⇨コードにドラッグで繋がります。
次に、NextViewControllerのパーツとコードを繋ぎます。
- 背景の青
- UIimageViewを画面いっぱいに貼り付け、backgroundでcolorを変更しています。
- Labelを1つ追加
- 画面遷移でViewControllerのカウントを表示するラベル。
- Buttonを1つ追加
- 戻るボタンで、ViewControllerの画面に戻ります。
ストーリーボードとコードを繋ぐ際は、Control+左クリック⇨コードにドラッグで繋がります。
ViewControllerのコード
2. ラベルの初期設定
countLabelという名前でストーリーボード上のラベルと繋がっています。そのラベルの値を、viewDidLoad内で”0”と指定しました。これで、アプリが起動すると、ラベルの初期値が、0 となります。ダブルクォーテーションで、数字のゼロを囲って宣言していますので、このゼロはString型(文字列型)です。後で、ご説明しますが、足したり引いたりするには、型変換しなければなりません。
var count = 0 は後で、足したり引いたりする際に利用する変数です。とりあえず宣言だけここで済ませています。なお、この宣言のように数字だけ入れると、swiftが独自に数値であると認識し、Int型と自動で設定されています。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var countLabel: UILabel!
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
countLabel.text = "0"
// Do any additional setup after loading the view.
}
3. ボタンのアクション指定
次に、ボタンが押された時のアクションを作成していきます。
先ほど触れましたが、countLabelのテキストにはstring型(文字列型)が入っています。そこで、数字として足したり引いたりするために、型変換をします。3行目で、Int型へ変換しています。これで数字として扱えるようになったため、+1と後に付け加えても、エラーとなりません。
3行目と4行目の内容をまとめると⇨
- countLabelをInt型に変換し、+1足します。(3行目)
- 足し合わせた数字をcount変数に入れます。(3行目)
- countはInt型なので、String型に変換します。(4行目)
- String型となったcountを、countLabelに入れます。(4行目)
5行目と6行目は、条件が達せされると、画面遷移するように、if文を使用しています。countが10または−5とイコールとなった場合、画面遷移します。6行目に”next”とありますが、これは、Storyboard Segueのidentifierで付けた名前(2つのViewController間の矢印に付けた名前)と同じ名前を入力します。
//カウントアップボタンのアクション内容
@IBAction func countUp(_ sender: Any) {
count = Int(countLabel.text!)! + 1
countLabel.text = String(count)
if count == 10 || count == -5 {
performSegue(withIdentifier: "next", sender: nil)
}
}
カウントダウンボタンも、カウントアップボタンとほぼ同じような内容で、ボタンが押されると、数字を引いていきます。そして、10または-5とイコールとなると、画面遷移します。
//カウントダウンボタンのアクション内容
@IBAction func countDown(_ sender: Any) {
count = Int(countLabel.text!)! - 1
countLabel.text = String(count)
if count == 10 || count == -5 {
performSegue(withIdentifier: "next", sender: nil)
}
}
このままでは、画面が変わるだけですので、次に、データを遷移させる方法をご説明します。
4. 画面遷移(値渡しのメソッド)
次に、画面遷移ボタンのアクションと、画面遷移で呼ばれるメソッドの設定をします。(画面遷移が起きると自動で呼ばれるコード)
画面遷移ボタンは、先ほど、if文の条件達成後のアクションと同じで、PerformSegueを指定します。画面遷移が起きた時に呼ばれるメソッドですが、7、8行目はこのまま覚えてもらえればと思います。nextVCというのは、こちらで指定した名前ですので、変更可能です。今回使用したnextVCは、NextViewContorollerの略として、分かりやす名前として付けています。
10行目が、遷移先に値を渡すコードです。countはViewController内で利用していた変数で、こちらにカウントアップとカウントダウンで得られた数値がInt型で入っています。nextVC.count2は、まだこの段階では指定していませんが、Next viewControllerで利用する変数です。ですので、count2をNext ViewControllerで宣言する前に、10行目を記述すると、エラーが出ます。ただし、10行目の記述が先か、NextViewControllerでのcount2の宣言が先かは、どちらでも構いません。宣言すれば、エラーは消えてくれます。
これで、countの値をcount2という変数に渡すことができました。
//画面遷移ボタンのアクション内容
@IBAction func senyi(_ sender: Any) {
performSegue(withIdentifier: "next", sender: nil)
}
//画面遷移が起きると呼ばれるメソッド
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let nextVC = segue.destination as! NextViewController
nextVC.count2 = count
}
} //ViewControllerクラスの終了
NextViewControllerのコード
5. 画面遷移先の初期設定
次に、画面遷移先のNextViewControllerのコードを作成していきます。
label1は、ストーリーボードのLabelと繋げます。(Control+左クリック、コードにドラッグで繋がります。)
7行目のcount2、これを宣言することで、ViewControllerのエラーが消えます。
import UIKit
class NextViewController: UIViewController {
@IBOutlet weak var label1: UILabel!
var count2 = 0
viewDidLoad内に、label1に表示する内容を指定します。コード自体は簡単で、3行目の1行のみです。count2は、ViewControllerで遷移が起きた時、countの値が入っています。その値を、NextViewControllerが表示された時に、lavel1に表示するよう指定しています。
override func viewDidLoad() {
super.viewDidLoad()
label1.text = String(count2)
// Do any additional setup after loading the view.
}
6. ボタンのアクション指定(戻るボタン)
最後に、戻るボタンのアクション内容です。3行目をこのまま記述していただければ、ViewControllerに戻ることができます。NextViewConttollerからViewControllerへの値渡しがない場合は、この1行のみで済むので簡単です。
//戻るボタンのアクション内容
@IBAction func back(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}//クラスの終了
全コード
ViewController
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var countLabel: UILabel!
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
countLabel.text = "0"
// Do any additional setup after loading the view.
}
//カウントアップボタンのアクション内容
@IBAction func countUp(_ sender: Any) {
count = Int(countLabel.text!)! + 1
countLabel.text = String(count)
if count == 10 || count == -5 {
performSegue(withIdentifier: "next", sender: nil)
}
}
//カウントダウンボタンのアクション内容
@IBAction func countDown(_ sender: Any) {
count = Int(countLabel.text!)! - 1
countLabel.text = String(count)
if count == 10 || count == -5 {
performSegue(withIdentifier: "next", sender: nil)
}
}
//画面遷移ボタンのアクション内容
@IBAction func senyi(_ sender: Any) {
performSegue(withIdentifier: "next", sender: nil)
}
//画面遷移が起きると呼ばれるメソッド
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let nextVC = segue.destination as! NextViewController
nextVC.count2 = count
}
}
NextViewController
import UIKit
class NextViewController: UIViewController {
@IBOutlet weak var label1: UILabel!
var count2 = 0
override func viewDidLoad() {
super.viewDidLoad()
label1.text = String(count2)
// Do any additional setup after loading the view.
}
//戻るボタンのアクション内容
@IBAction func back(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}