開発メモ

開発関係のメモをいろいろと。たぶん。

iOS向けアプリで複数の画像を切り替え

はじめに

単純に用意した画像を表示するだけで無く、表示する画像をボタンで切り替えられるようにしてみます。

作業の手順としては、こんな感じになります。

  1. 画像を表示するところまで作成
  2. ストーリーボードで切り替えに使うボタンを設置
  3. ストーリーボードでボタンとソースコードを接続
  4. ボタンが押されたとき、画像を切り替える
  5. 表示できる画像の範囲をチェック

ソースコードはこちら。

See_Ku / SwitchingImage — Bitbucket
https://bitbucket.org/See_Ku/switchingimage

動作環境

環境 情報
Xcode 7.3.1 (7D1014)
iOS 9.0
Swift 2.2
Date 2016/7/2

1. 画像を表示するところまで作成

以前、『iOS向けアプリで画像を画面に表示』というネタを書いたので、こちらを参考にしてImage Viewに画像を表示するところまで作業しておきます。

iOS向けアプリで画像を画面に表示 - 開発メモ
http://seeku.hateblo.jp/entry/2016/07/02/160916

今回は複数の画像を切り替えられるようにするので、プロジェクトに複数の画像を追加しておきます。ここでは3枚の画像を追加してみました。

f:id:see_ku:20160702204606p:plain

2. ストーリーボードで切り替えに使うボタンを設置

画像の切り替えに使用するボタンを設置します。今回は前の画像に戻るボタンと、次の画像に進むボタンを使用します。

f:id:see_ku:20160702204620p:plain

ボタンのタイトルはわかりやすい内容に変更しておきましょう。

f:id:see_ku:20160702204632p:plain

ボタンを置く位置やオートレイアウトの設定はお好みでどうぞ。ここでは、こんな感じにしてみました。

f:id:see_ku:20160702204644p:plain

3. ストーリーボードでボタンとソースコードを接続

ボタンが押されたタイミングで、何らかの処理が行えるように接続しておきます。

f:id:see_ku:20160702204657p:plain

ダイアログが表示されるので、接続の詳細を設定します。ConnectionをActionに変えるのをお忘れ無く。

f:id:see_ku:20160702204707p:plain

ボタンが2個あるので、両方とも同じようにして接続しておきます。

この時点で、ViewController.swiftはこんな感じになってます。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    @IBAction func onPrev(sender: AnyObject) {
    }

    @IBAction func onNext(sender: AnyObject) {
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let image = UIImage(named: "fruit_melon_cut_orange")
        imageView.image = image
    }

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

}

4. ボタンが押されたとき、画像を切り替える

複数の画像を切り替えるような処理を行う場合、まず、『表示している画像の番号』を示す変数を作っておいて、それを元に画像を表示させるのが定番の処理です。

こうしておくと、次の画像を表示する処理はこんな感じになります。

  1. 表示している画像の番号を1増やす
  2. 表示している画像の番号を元に画像を表示する

前の画像に戻す処理はこんな感じになります。

  1. 表示している画像の番号を1減らす
  2. 表示している画像の番号を元に画像を表示する

『表示している画像の番号を元に画像を表示する』の部分は、どちらでも同じ処理が使えそうですよね? これをそのままプログラムに落とし込むと、こんな感じになります。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    @IBAction func onPrev(sender: AnyObject) {

        // 表示している画像の番号を1減らす
        dispImageNo -= 1

        // 表示している画像の番号を元に画像を表示する
        displayImage()
    }

    @IBAction func onNext(sender: AnyObject) {

        // 表示している画像の番号を1増やす
        dispImageNo += 1

        // 表示している画像の番号を元に画像を表示する
        displayImage()
    }

    /// 表示している画像の番号
    var dispImageNo = 0

    /// 表示している画像の番号を元に画像を表示する
    func displayImage() {

        // 画像の名前の配列
        let imageNameArray = [
            "fruit_melon_cut_orange",
            "fruit_slice10_orange",
            "fruit_slice11_kiwi",
        ]

        // 表示している画像の番号から名前を取り出し
        let name = imageNameArray[dispImageNo]

        // 画像を読み込み
        let image = UIImage(named: name)

        // Image Viewに読み込んだ画像をセット
        imageView.image = image
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let image = UIImage(named: "fruit_melon_cut_orange")
        imageView.image = image
    }

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

}

これで一応、画像の切り替えは出来るようになりましたが・・・ 起動直後のPrevボタンを押すと、いきなり落ちます。Nextボタンを何回も押してても落ちます。これではまずいのでどうにかしましょう。

5. 表示できる画像の範囲をチェック

PrevやNextでアプリが落ちるのは、この行が原因です。

        // 表示している画像の番号から名前を取り出し
        let name = imageNameArray[dispImageNo]

dispImageNoをインデックスに使って配列から名前を取り出してますが、この時、dispImageNoが配列の範囲外を指してるとアプリが落ちてしまいます。落ちないようにするため、この前に範囲のチェックを入れましょう。

具体的には、こんな感じになります。

    /// 表示している画像の番号を元に画像を表示する
    func displayImage() {

        // 画像の名前の配列
        let imageNameArray = [
            "fruit_melon_cut_orange",
            "fruit_slice10_orange",
            "fruit_slice11_kiwi",
        ]

        // 画像の番号が正常な範囲を指しているかチェック

        // 範囲より下を指している場合、最後の画像を表示
        if dispImageNo < 0 {
            dispImageNo = 2
        }

        // 範囲より上を指している場合、最初の画像を表示
        if dispImageNo > 2 {
            dispImageNo = 0
        }

        // 表示している画像の番号から名前を取り出し
        let name = imageNameArray[dispImageNo]

        // 画像を読み込み
        let image = UIImage(named: name)

        // Image Viewに読み込んだ画像をセット
        imageView.image = image
    }

実際に動かすとこんな画面になります。

f:id:see_ku:20160702204728p:plain

これで、特に問題なく画像を切り替えることが出来るはずです。たぶん。もっと画像を増やすとどうなるか・・・ 発展課題としてやってみると良いかも知れません。

謝辞

画像はいらすとやさんの物を使わせていただきました。

無料イラスト かわいいフリー素材集 いらすとや
http://www.irasutoya.com/