カテゴリー: iOS

Swift3で動的にUIViewを切り替える Part2

はじめに

どうも、はじめです。

前々回にExtraViewを使って画面の切り替えを行う方法を書きましたが
ContainerViewというものを使ってみてかなり便利なことがわかったので
備忘録的な意味も含めて今回記事を書いてみようと思います。

 

前提条件

Swift3.1

 

完成イメージ

完成イメージとしては以下のような画面になります。

動きとしては、
SegmentのFirst、Secondを選択すると、[ContainerView A]と書かれている部分が切り替わり、
それとは別に固定のViewが一つ存在している状態となります。

 

StoryBoardの準備

Viewの配置

まずはじめにわかりやすいように以下の3つのViewを用意します。
① Segmentを配置するView
② ContainerViewを配置するView
③ 固定Viewを配置するView

 

① Segmentを配置するView

このViewにはSegmentを一つ配置するだけです

 

② ContainerViewを表示するView

このViewには枠いっぱいのContainerViewを2つ重ねて配置します。
加えて、ContainerViewの切り替えがわかるようにそれぞれのContainerViewに対し、
背景色の設定とLabelの追加をしておきます。

 

③ 固定Viewを表示するView

固定で表示させるViewということが分かるように、
こちらにも背景色の設定とLabelの追加をしておきます。

 

以上でStoryBoardの設定は完了です。
設定後のStoryBoardは以下のようになります。

 

SegmentでContainerViewの切り替えを実装

今回それぞれのContainerViewの中で処理は実装しないので
MainのViewに紐づくVIewControllerのみの実装となります。
実装完了後のソースは以下になります。

import UIKit

class ViewController: UIViewController {

    // ①
    @IBOutlet weak var containerView: UIView!
    @IBOutlet weak var containerA: UIView!
    @IBOutlet weak var containerB: UIView!
    var containers: Array<UIView> = []

    // ②
    override func viewDidLoad() {
        super.viewDidLoad()
        containers = [containerA,containerB]
        containerView.bringSubview(toFront: containerA)
    }

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

    // ③
    @IBAction func changeContainerView(_ sender: UISegmentedControl) {
        let currentContainerView = containers[sender.selectedSegmentIndex]
        containerView.bringSubview(toFront: currentContainerView)
    }
}

 

それでは上記ソースに関して各項目ごとに解説を書いていきます。

①各変数、配列の定義

以下の三つをIBOutlet接続します
・containerAとBの親ViewであるUIView(以後「containerView」と記述させて頂きます)
・containerViewA
・containerViewB
さらに、後で使用するcontainersというUIViewを格納する配列を作成しておきます。

 

②Load時の処理

①で作成したcontainersという配列にcontainerAとcontainerBを格納し、
明示的にcontainerAをcontainerView内の最前面に配置します。

 

③ContainerViewの切り替え

Segmentからcontrol+ドラッグ&ドロップしてIBActionを作成します。
※typeを「UISegmentedControl」に設定してください

選択されたSegmentのIndexをKeyとして配列containersから該当するContainerViewを取得し、
containerView内で最前面に配置します。

 

以上で全ての実装が完了となります。

 

さいごに

ContainerViewを使用すると切り替えたい画面中での複雑な処理の実装が簡単に行えます。
注意しておきたいのはContainerViewはwillRemoveSubview()してもStoryBoard上から削除されるわけではないこと。
(addSubView()やwillRemoveSubview()をしても親View内での配置順序が変わるだけでした。)
ContainerViewに紐づくViewControllerファイルがLoadされるタイミングがMainとなるViewが表示される時なのでこちらも把握しておく必要があります。

 

最後まで見て頂きありがとうございました。

何か間違い等あった場合はぜひコメントを頂ければと思います。

hajimenagasawa

コメントを見る

  • haimenagasawa様

    お世話になっております。
    iOSアプリを個人で開発している齋藤と申します。
    突然のご連絡申し訳ございません。

    iOSアプリの実装方法について、ご教授いただきたくご連絡いたしました。

    hajimenagasawa様の下記ページを参考に動的にUIViewを切り替える機能を実装することができましたが、このContainerViewのAとBを左右スワイプでも画面を切り替えるようにしたいと考えております。

    上記の機能を追加するためには、UIPageViewControllerを使用することが考えられますが、どのように実装したらよいか知識不足のため、分かっておりません。

    大変恐縮ではございますが、ContainerViewの画面切り替えに加え、左右スワイプでも画面が切り替えられるようにするには、どのように実装したらよいかアドバイスをいただけないでしょうか。

    ■参考ページ
    https://re-engines.com/2017/07/21/swift3%E3%81%A7%E5%8B%95%E7%9A%84%E3%81%ABuiview%E3%82%92%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88%E3%82%8B-part2/

    • 齋藤様

      RE:ENGINESブログの閲覧ありがとうございます。
      ご質問に対する回答はnukkyが担当させていただきます。

      ContainerView左右スワイプでの切り替えですがUIPageViewControllerを使用しての切り替えも良いとは思いますが、こちらのブログの内容で実装済みなのであれば、UISwipeGestureRecognizerを使って実装するのが手早くできると思います。
      UISwipeGestureRecognizerのコードのサンプルを書いておきますので参考にしていただければと。
      実装としてはブログのchangeContainerViewで行っている内容を以下のコードのleftSwipeView、rightSwipeViewで行っていただければうまくいくと思うので頑張ってください。
      ////以下サンプルコード////

      override func viewDidLoad() {
          super.viewDidLoad()
          // レフトスワイプを定義
          let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.leftSwipeView(sender:)))
          // レフトスワイプのみ反応するようにする
          leftSwipe.direction = .left
          // viewにジェスチャーを登録
          self.view.addGestureRecognizer(leftSwipe)
          // ライトスワイプを定義
          let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.rightSwipeView(sender:)))
          // ライトスワイプのみ反応するようにする
          rightSwipe.direction = .right
          // viewにジェスチャーを登録
          self.view.addGestureRecognizer(rightSwipe)
      }
      // レフトスワイプ時に実行される
      @objc func leftSwipeView(sender: UISwipeGestureRecognizer) {
          print("left Swipe")
      }
      // ライトスワイプ時に実行される
      @objc func rightSwipeView(sender: UISwipeGestureRecognizer) {
          print("right Swipe")
      }
シェア
執筆者:
hajimenagasawa
タグ: Swift

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

2週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

4週間 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前