リブートキャンプ by Swift 目次

 

 場所移動用のマップ画面なんかは、今までに得た知識で十分表示できるわけでして…

 要するに、今のself.viewに新しいUIView追加すりゃいいわけですよ。

 でもって、用がなくなれば画面を隠すなり、取り外すなりすればいいわけです。

 ちなみにUIViewの取り外しは、addSubviewの時のように親側UIViewじゃなく、取り外される子側のUIViewにremoveFromSuperview()メッセージを送ります。

 

取り付ける時:

  親UIViewオブジェクト.addSubview( 子になるUIViewオブジェクト )

 

取り外す時:

  子UIViewオブジェクト.removeFromSuperview()

 

 で、追加するUIViewの中に、サブ画面としてUIImageViewとか貼り付けて地図出すとか、そのまた上に別のUIImageView貼り付けて、キャラクタのアイコンなりを表示させて現在位置を示すとか、色々やればいいわけです。

 なんならアニメーション付きでマップ画面出しましょうか、くらいのこと言う猛者もいるとは思うし、それで正解ちゃ正解なんですが…

 

 そうやって調子こいて、今までみたいにViewControllerに処理追加していくと、どんどんViewControllerのソースコードが肥大化するわけですな。

 で、半年くらい時間あけて見直した時に、コードが込み入りすぎてて「何やりたかったんだ、俺?」みたいなことになっちゃう。

 今でも十分、リファクタイリング(再因子化。現行のソースコードの関数やクラス定義を見直して、見通しの良い構造に組み替える)したいレベルなんですが、これ以上悪化させないためにはどうするか?

 こういう場合、UIViewを派生させてマップ画面専用のUIView派生クラスを作ったりします。

 

 class MapView : UIView {

   ・・・

  }

 

 そのままViewController.swiftにMapViewクラスの定義を書いてもいいんだけど、クラス定義ってのは、ファイルを分離するのに、ちょうどいい感じの単位なんで、大概は別ファイルにします。

 新しいswiftファイルを作るには、File→New→File…メニューを選んで、出てきた画面でSwift Fileテンプレート選択てのが一番基本なんですが、UIKit系の派生クラス用ならCocoa Touch Classテンプレートを使いましょう。

 

 

 Cocoa Touch Classテンプレートを選ぶと、次の画面ではこんな感じでUIViewを派生させて、MapViewクラス用意しますってのを指定する。

 

 その次の画面は、ファイルをどこに置くかの指定。プロジェクトフォルダ内が表示されてると思うので、そのまま保存でOK。そうすっとナビゲーションエリアにMapView.swift項目が追加されます。

 

 

 あらかじめUIViewの派生としてMapViewクラスの定義まで書いてくれてるので、あとは必要な処理として、作成時に地図画像用のサブ画面準備とか、ユーザーのタップに対する対応とかの関連作業をやっちゃえば、ViewController側は、そのMapViewを作ってself.viewに追加する程度で地図画面対応ができるわけっす。

 

        let mapView = MapView(frame:self.view.bounds)

        mapView.frame.origin.y = mapView.frame.maxY

        self.view.superview?.addSubview(mapView)

        UIView.animate(withDuration: 1) {

            mapView.frame.origin.y = self.view.bounds.origin.y

        }

 

ちなみに作ったMapViewは、self.viewじゃなく、self.view.superviewとして、self.viewの親UIViewに追加してます。

 こんな感じで、superviewプロパティには親側UIViewの参照が設定されとります。どこにもaddSubviewされてないUIViewの場合はsuperviewはnilになるんでオプショナルっす。オプショナルがわからん人は「アンラップしてチン♪」を読みましょう。親UIViewに追加する理由は次回。

 

 この例では、単に追加じゃなく、下から迫り上がるアニメーションでMapViewを追加表示してる。

 でもって、表示されたMapViewは、下に向けてのスワイプで画面を閉じるようにしました。こっちもアニメーション付き。

 

サンプル:

http://tetera.jp/xcc/book-sample/modalview.zip

 

 なんですが…

 実はAppleはこの手の画面切り替えをUIViewController間で行うことを推奨してまして…

 こんな感じで全面にマップ画面を出すなら、UIViewControllerを派生させてMapViewControllerなんかを定義して、これとViewController間で切り替えを行う、ってのがiOSアプリでの王道ってことになっとります。

 

 そこんところや、今回のUIViewの派生方法なんかは次回!