Views
プロジェクトを実行することができたので、画面上にものを配置してみましょう。
アプリケーションで表示されている「もの」は「ビュー」と呼ばれます。1 つのビューはたくさんの「サブビュー」を持つことができます。ビューを移動するときには、そのサブビューも移動します。サブビューは、親のビュー上で階層状に積み重ねられます。
コードでは、これらは UIView
オブジェクトになります。画面上で目にするすべてのものは UIView
の子孫です。それらは便利な機能をたくさん持っていますが、今すぐに気にすべきなものは次の機能です。
frame
プロパティは、 ビューのx
とy
座標、ビューの大きさであるwidth
とheight
という値からなります。subviews
プロパティは、ビューのすべてのサブビューからなる配列で、背後から前面という視覚的な並びになっています (subviews
の配列からビューを取り出すときに指定する index 値は、そのビューの "z-order" のような感じです)。
frame
は、ビューの形や親のビューとの相対的な位置を表します。説明が多いので、簡単な例を示します。座標 (10, 10) にビューがあるのを想像してください。そのビューの新しいサブビューとして、画面上の座標 (50, 50) に表示されるビューが欲しいです。そのため、新しいビューの frame に座標 (40, 40) を設定する必要があります。わかりました?
アプリケーションの基本となるビューは "window" です。ほかのすべてのビューは window のサブビューか、またはそのサブビュー (またそのサブビュー、そのまた・・・) です。 アプリケーションの window は UIWindow
と呼ばれる UIView
のサブクラスです。
さぁ、コードを書いてみましょう。AppDelegate
の didFinishLaunching
メソッドを次のように変更します。
def application(application, didFinishLaunchingWithOptions:launchOptions)
# UIScreen describes the display our app is running on
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
@window.makeKeyAndVisible
@blue_view = UIView.alloc.initWithFrame(CGRectMake(10, 10, 100, 100))
@blue_view.backgroundColor = UIColor.blueColor
@window.addSubview(@blue_view)
true
end
このコードをたどってみましょう。画面の大きさの UIWindow
インスタンスを作成し、makeKeyAndVisible
を呼び出しています。これは、基本的にこの window は 1 つのタッチイベントを受信し画面上に表示される必要があることを OS に指示しています。(もし興味があれば複数の画面に複数の window を表示することができますが、ここでは小さな第一歩を刻みましょう)。
window を作成し、それから、window のサブビューとして新しいビューを作成します。ビューの frame には、実際には CGRectMake(x, y, w, h)
を使用して作成した CGRect
オブジェクトが格納されています。気をつけてください!CGRect
は実際には 2 つのオブジェクト CGPoint
と CGSize
で構成されます。座標 y を参照したい場合には view.frame.position.y
、高さを参照したい場合には view.frame.size.height
となります。
また、色で遊ぶ方法について UIColor
が示されています。UIColor
はいくつか明確なデフォルト値 (blueColor
, redColor
など) がありますが、任意の配色を作成するために使用することができます。
FULL DISCLOSURE: UIWindow
に UIView
を単独で直接追加することは一般的に良い考えではありませんが、勉強するためには良いことです。そのため、製品のコードではそれを行いません。
アプリケーションを実行すると (rake
を実行します。覚えてる?)、青いボックスが見て取れます。
もっとボックスを追加して、よりエキサイティングにしましょう!
...
@blue_view = UIView.alloc.initWithFrame(CGRectMake(10, 10, 100, 100))
@blue_view.backgroundColor = UIColor.blueColor
@window.addSubview(@blue_view)
@green_view = UIView.alloc.initWithFrame(CGRectMake(30, 30, 40, 40))
@green_view.backgroundColor = UIColor.greenColor
@window.addSubview(@green_view)
@red_view = UIView.alloc.initWithFrame(CGRectMake(30, 30, 40, 40))
@red_view.backgroundColor = UIColor.redColor
# NOTE: *not* adding to @window
@blue_view.addSubview(@red_view)
...
再び rake
を実行します。赤いビューが緑のビューよりも下側にあることがわかります。一見、同じ frame
にもかかわらず?
おもしろいので、インタラクティブな REPL
で遊んでみましょう。rake
を実行した Terminal は、シミュレータを開いている間、irb
のようなプロンプトが表示されます。さぁ、@blue_view
を見つけてみましょう。
> delegate = UIApplication.sharedApplication.delegate
=> #<AppDelegate>
> blue_view = delegate.instance_variable_get('@blue_view')
=> #<UIView>
私たちは何をしたのでしょうか? UIApplication.sharedApplication
は、システムがアプリケーションを描画するために使用するオブジェクトを返してくれます。delegate を使用するための設定について以前述べましたが、 .delegate
で返されるものはそのオブジェクトです。そのオブジェクトを手に入れれば、ビューを取得するために、便利な instance_variable_get
を使うことができます。
ビューがサブビューを 1 つ持っていることを blue_view.subviews.count
で確認することができます。red_view
を取得して、そのビューを削除してみましょう。
> blue_view.subviews.count
=> 1
> red_view = blue_view.subviews[0]
=> #<UIView>
> red_view.removeFromSuperview
=> #<UIView>
ビューは消えました。removeFromSuperview
メソッドは、自身のビューを画面から削除します。そして、red_view は親のビューの subviews
でした (再び blue_view.subviews.count
を実行することで確認できます)。
Wrap Up
この例はそれほど長くはありませんでしたが、ビューの核となるコンセプト、ビューには frame とサブビューがあることを説明しました。例ではシンプルでしたが、実際にアプリケーションを作成するとはるかに複雑になります。したがって、私たちはそれらを対処するためにより良い基盤が必要です。
まとめ
- 画面上のすべてのものは
UIView
です。 - アプリケーションの基本となるビューは
UIWindow
のインスタンスです。ほかのビューはUIWindow
の子孫です。UIWindow
を delegate で作成します。 - ビューはサブビューを持っていて、
UIView#addSubview
で追加します。サブビューはお互いの上に積み重ねられます。