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

↑結構溜まったんでまとめました

 

 前回、画面は階層化できるって話をしましたが、そこらへんをもうちょっと具体例で示してみます。

 それと、任意の文字列を表示できるUILabelがテキストの基本なら、もう一つ、グラフィックの基本UIImageViewも知ってないとあかんでしょうということで、そっちも紹介しておく。

 

UIImageView

 

 こいつは、既存のPNGやJPEG画像を画面に表示するUIView派生クラス。

 基本的な扱いはUILabel(つまりUIView)と同じで、親画面上の矩形を指定して作り、addSubviewで子供にします。

 違うのは、表示する内容が画像なんでtextプロパティじゃなくimageプロパティってのを持っている点。

 なので、前回のUILabel版プロジェクト風にやるなら、次のようになります。

    override func viewDidLoad() {
        super.viewDidLoad()
        let imageView = UIImageView(frame:CGRect(x: 50, y: 100, width: 200, height: 200))
        imageView.image = UIImage(named: "girl")
        self.view.addSubview(imageView)
    }

 そして、imageプロパティには文字列ではなく画像を指定しなきゃならんわけですよ。

 で、画像はUIImageというオブジェクトで表現します。

 

UIImage

 

 こいつを作るときは、プロジェクトに登録した画像ファイルの名前を指定して作るのが基本。今回なら"girl"が画像ファイルの名前です。

 利用する画像ファイルは、プロジェクトにあらかじめ用意されているAssets(アセット:資産という意味じゃよ)フォルダにPNGやJPEG画像ファイルをドラッグ&ドロップして登録します。

 

 

 この時に、ファイル名がそのままAssets内での名前になり、これをUIImage作成時に指定することになるわけです。

 登録された項目を選ぶと、横の画面にサムネイルが出ます。

 2x、 3xとあるのは、iPhone 7、iPhone 7 Plusにそれぞれ最適化した画像をしてする場合用です。なければないで、1xが拡大されて使い回される。

 

 

 

 

 ちなみに、サンプルのgirl.pngは289 × 431ピクセルの大きさなので、iPhone 7用だとその2倍の578 × 862ピクセルの大きさの画像、iPhone 7 Plusだと3倍の867 x 1293ピクセルの大きさの画像を指定することになります。
 登録したらファイルのコピーがプロジェクトフォルダ内に作成されるので、元のファイルは捨てるなり保存するなり好きにしてください。

 

 ここまでできたらRun。

 

 ↓こんな感じの画面が開くことになります。

 

 

サンプル:

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

 

 女の子が太ってるのは、元々の画像が289 × 431 ピクセルなのを、200 x 200 ポイントの矩形にスケーリングして表示してるから。解決法は色々あるけど、何も指定しないとこうなります。

 サンプルいじってimageViewの矩形を縦長にしたり色々大きさを変えて試してみるといいでしょう。

 

 上で出てきた「ポイント」は、フォントの大きさを指定する単位で、1ポイント=1/72インチという大きさです。iPhoneでは画面座標もこの単位で指定します。

 例えば、物理的な液晶の画素(ピクセル)は、初代iPhoneで横320ピクセル、iPhone 4、5では640ピクセルと、初代の2倍になってるんですが、ポイント座標での表現はどちらも320ポイントとなります。

 座標の横1ポイントの大きさに画素が1個なのが初代、2個なのがRetinaディスプレイ搭載と言われるiPhone 4以降の機種。

 より画面がきめ細やかになったわけですな。

 

 

 ちなみにiPhone 6 plusで導入されたRetina HDディスプレイだと1ポイントの画素は3個と、初代の3倍となります。

 

 ↓並べるとこんな感じ(S,SEは省略)

 

         液晶画素数  ポイント  倍率 

初代       320     320    x1

4、5        640     320    x2

6、7        750     375    x2

6 plus、7 plus  1080     360    x3

 

 液晶画素数だとかなりの開きがあるんですが、ポイントで座標を指定してる限り、画面上に表示される物理的な大きさはそこそこ統一されます。

 6以降は物理的な横幅が広くなってるのでポイントも広がってる。

 まあ、これがAssetsでのx1、x2、x3の意味でもあります。最近インフレ気味なんでPDFのベクター画像もサポートするようになりました。

 

UIView画面の階層化

 

 で、いよいよUIView画面の階層化の話です。

 今度は背景用の画面(UIImageView)の上に、前景用の画面(UIView)をかぶせてみます。で、その前景用の画面には少女の画面用(UIImageView)とセリフ画面用(UILabel)が子画面として登録されている。

 

 

 

 

 

    override func viewDidLoad() {
        super.viewDidLoad()

        //  背景
        let backgroundImageView = UIImageView(frame:CGRect(x: 0, y: 0, width: 300, height: 300))
        backgroundImageView.image = UIImage(named: "back")
        self.view.addSubview(backgroundImageView)

        //  セリフ付き前景
        let baseView = UIView(frame: CGRect(x: 20, y: 200, width: 260, height: 100))

        //  人物
        let imageView = UIImageView(frame:CGRect(x: 0, y: 0, width: 150, height: 220))
        imageView.image = UIImage(named: "girl")
        baseView.addSubview(imageView)

        //  セリフ
        let message = UILabel(frame: CGRect(x: 90, y: 130, width: 160, height: 40))
        message.backgroundColor = UIColor.orange
        message.text = "ここを通りたくば、私と"

        baseView.addSubview(message)
        self.view.addSubview(baseView)
    }

 どこにaddSubviewされてるかを注意しましょう。

 でRunすると次のようになります。

 

 

 で、これの最後に以下を付け加えてやると

    ・・・
        baseView.addSubview(message)
        self.view.addSubview(baseView)
        
        baseView.frame = CGRect(x: -50, y: 120, width: 260, height: 100)
    }

前景用の画面がまとめて移動することになるわけですな。

 

 

サンプル:

http://tetera.jp/xcc/book-sample/image-hierarchy.zip

 
 iPhoneのアプリの画面ってのは、こういうUIView、またはその派生クラスのオブジェクトの組み合わせで作り上げられとるわけですよ。
 以上、画面階層の話でした。
 ち・な・み・に、自分のアプリの画面の階層化され具合をみてみたい人は、Run中にDevag View hierarchyボタンをクリックだ!
 
 
 次回は、ここら辺の情報をどうやって見つけ出していくかについて…
 全員シャルジャー!
 
AD