19
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TECH PLAY女子部Advent Calendar 2017

Day 11

Swiftでおみくじアプリをつくる

Last updated at Posted at 2017-12-11

夏頃から会社の仲間とSwiftを勉強し始めました。
簡単なおみくじアプリ作成の流れをまとめて、自分の理解を深めようと思います。

#作成したいおみくじアプリ
##条件
1.名前と年齢を入力させる
2.大吉、中吉、小吉、凶をランダムに表示する。
3.もう一度ボタンを押したら、テキストフィールドは空になっている
##画面イメージ
image.png

#Xcodeを起動し、プロジェクトを作成する
Xcodeを起動後、「create a new Xcode project」を選択
スクリーンショット 2017-12-12 1.19.49.png

Single New Appを選択し、「NEXT」
スクリーンショット 2017-12-12 1.22.59.png

project nameに好きな名前をつけて「NEXT」を押すと、
プロジェクトのディレクトリが作成されます。
スクリーンショット 2017-12-12 1.24.45.png

プロジェクトの作成が完了したら、以下の流れでアプリを作成していきます。
①画面を作る
②2つのページそれぞれの処理を書く
③2つのページを繋げる処理を書く
④データ保存の処理を書く

#①画面を作る
アプリの画面は、「Main.storyboard」から作っていきます
画面一番左の「Main.storyboard」をクリックします。
スクリーンショット 2017-12-12 1.35.57.png

##入力画面を作る
アプリに必要なパーツを右下のメニューから選択します。
test_readme_img.gif

まずは入力画面にある「年齢を入力」と表示させるラベルを配置します。
フィルタで「label」と検索し、画面上でドラッグアンドドロップし、文字を書き換えます。
同様に、「textField」「button」を配置していきます
スクリーンショット 2017-12-12 1.53.00.png

##おみくじ結果画面を作る
次に2ページ目のおみくじ結果を表示させる画面を作成します。
右下メニューからviewControllerを検索しドラッグアンドドロップします。
結果の表示に必要な、label、buttonを配置します。
スクリーンショット 2017-12-12 1.55.50.png

#②つのページそれぞれの処理を書く
ここで、左上にある再生ボタン(▶)を押すと、1ページ目である入力画面が表示されます。
ここから、ページそれぞれの処理を書いていきます。

##入力画面の処理
入力画面には年齢と名前、2つの値を入力するtextFieldがあります。
それぞれの値を次のページに渡したり、データとして保存するために、変数に格納する処理を実装していきます。
アプリの一つひとつの画面に処理を実装するためには、その画面に対応した「ViewController」に処理を記載していく必要があります。
1ページ目の入力画面は「viewController.swift」がそれにあたります。

###年齢のtextFieldを変数に格納する
Controllerキーを押しながらテキストフィールドをドラッグアンドドロップし、
画面上のtextFieldとViewControllerを紐付けます
2.gif
同様に名前のtextFieldも紐付けを行います

##おみくじ結果画面の処理
おみくじ結果画面ではまず、Controllerの作成が必要です。
Xcodeのメニューの、file>new>file から、「cocoa touch class」を選択し
「omikuziViewController」など任意の名前をつけ、「UIViewController」をプルダウンから選択し、
ファイルを作成します。
作成したファイルに必要な処理を書いていきます。

omikuziViewController.swift

import UIKit

class OmikuziViewController: UIViewController {

    //前のページから名前を受け取るための変数
    var name:String? = ""

    //おみくじの結果を配列に格納
    var result:[String] = ["大吉", "中吉", "小吉", "凶"]

    //名前とおみくじの結果を表示させるためのlabelを、Controllerと紐付ける
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var resultLabel: UILabel!
    
    //viewDidLoadはページが表示された時に実行される
    override func viewDidLoad() {
        super.viewDidLoad()

        //受け取ったnameにnilが入っていないかチェックをする
        if let name = name {
            //nilが入っていなかった場合、Labelに名前を表示させる
            nameLabel.text = name + "さん"
        }
        //ランダムな数値0〜3を取得、結果に応じて配列からおみくじの値を表示させる
        let num = Int(arc4random_uniform(4))
        resultLabel.text = "\(result[num])です!"
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    


}

#③2つのページを繋げる処理を書く
次に、2つのページを繋げるための処理を記載していきます。

##「結果」ボタンを押すと次のページに遷移するようにする
結果のボタンをおした時、次のページに遷移させるためには、
結果ボタンをControllerキーを押しながら次のページヘドラッグアンドドロップさせます。
3.gif

##おみくじの結果画面に入力した名前を渡す
1ページ目で記載した名前を2ページ目で表示させるため、nameの値の受け渡しを行う必要があります。
値の受け渡しを行うためには、
1.次のページの情報を取得する
2.次のページの中にある変数に、値を代入する
という手順をふみます

ViewControllerのClass内に、以下を記載します

viewController.swift
    //次の画面に名前を渡す処理
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        //次のページの情報を取得する
        //次のページはOmikuziViewController Classなので、それに合わせてas!でダウンキャストする
        let omikuziController = segue.destination as! OmikuziViewController
        
        //1ページ目の名前のtextFieldの値にnilが入っていないかチェックをする
        if let name = nameField.text {
            //nilチェックが通ったら、次のページのnameに、値を代入する
            omikuziController.name = name
        }        
    }

##「もう一度」ボタンを押した時の処理を書く
もう一度ボタンを押したときは、最初のページに戻るよう設定をします。
最初のページに戻るためには、最初のページのControllerに準備が必要です。

viewController.swift
    //前の画面から戻った時の処理
    @IBAction func restart(_ segue: UIStoryboardSegue) {

        //textFieldの値を空欄に戻す
        nameField.text = ""
        ageField.text = ""
    }

これで戻るための準備が整ったので、おみくじ結果ページの「もう一度」ボタンを押した時の設定を行います。
4.gif
#完成したもの
5.gif

#コード

viewController.swift
import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var ageField: UITextField!
    @IBOutlet weak var nameField: UITextField!
    
    //前の画面から戻った時に、フィールドの値を初期化する
    @IBAction func restart(_ segue: UIStoryboardSegue) {
        nameField.text = ""
        ageField.text = ""
    }
    
    //名前のテキストフィールドに文字が入力されるたびにユーザデフォルトに保存する
    @IBAction func nameFieldAction(_ sender: Any) {
        let ud = UserDefaults.standard
        if let name = nameField.text {
            ud.set(name, forKey: "name")
            ud.synchronize()
        }
    }
    
    //年齢のテキストフィールドに文字が入力されるたびにユーザデフォルトに保存する
    @IBAction func ageFieldAction(_ sender: Any) {
        let ud = UserDefaults.standard
        if let age = ageField.text {
            ud.set(age, forKey: "age")
            ud.synchronize()
        }
    }
    
    
    //次の画面に名前を渡す処理
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let omikuziController = segue.destination as! OmikuziViewController
        
        //名前を渡す
        if let name = nameField.text {
            omikuziController.name = name
        }
        
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        let ud = UserDefaults.standard
        let name = ud.string(forKey: "name")
        if let name = name {
            nameField.text = name
        }
        let age = ud.string(forKey: "age")
        if let age = age {
            ageField.text = age
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}
OmikuziViewController.swift
import UIKit

class OmikuziViewController: UIViewController {
    //前のページから名前を受け取る
    var name:String? = ""
    var result:[String] = ["大吉", "中吉", "小吉", "凶"]
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var resultLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if let name = name {
            nameLabel.text = name + "さん"
        }
        //ランダムな数値0〜3
        let num = Int(arc4random_uniform(4))
        resultLabel.text = "\(result[num])です!"
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

#まとめ
勉強開始してから、やっとシンプルながらもアプリっぽいものが作れるようになり、とても楽しいです。
ここ変だよーとか、間違ってるとかあったら反応いただけたら嬉しいです!
おわり

19
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?