【Swift】UIViewの使い方。部品はみんなこのクラスを継承している。(Swift 2.1、XCode 7.2)

2020年6月16日

UIViewとは

本記事では、Swiftで使える部品のUIViewについて説明する。

UIView(以下、ビュー)とは、デバイス画面上の描画やイベント受信をつかさどる部品で、デバイス画面に配置するすべての部品はUIViewを継承している。

View

 

ビューを使ってみる

ビューをデバイス画面に配置すると表示される透明な枠がビューである。

透明だと見づらいので背景色を変更しておこう。黄緑枠のアトリビュートインスペクタボタンから設定画面を開き、Backgroundを青色に変更する。

ビューをデバイス画面に配置する

 

これだけだと単純な四角枠で終わってしまうので、簡単な使用例を1つ。

下図のように、ビュー内の左上にラベルを配置する。ラベルが選択された状態で、黄緑枠のアトリビュートインスペクタボタンを押して設定画面を開き、Colorを白に変更する。

続いて、黄枠のPinボタンを押して吹き出しの設定画面を表示し、紫枠のアイコンを押して水平方向と垂直方向の制約を追加する。そして、「Add 2 Constraints」ボタンを押せばビューの中のラベルの制約が追加される。同じ手順で、ビュー内の右下にもう1つのラベルを追加する。

ビューの中にラベルを配置する

 

これにより、ビューとラベル2個で1セットととなり、ビューを移動すればラベル2個も一緒に移動する。また、デバイス画面内の位置はビューのみに制約を追加するだけで良くなるなどの利点がある。

ビューを移動する

 

ビューの設定項目

次に、ビューの設定項目を確認してみよう。ビューを選択した状態で、下図黄緑枠のアトリビュートインスペクタボタンを押して設定画面を表示する。

ビューのアトリビュートインスペクタ

 

Mode

ビューの領域に対して部品をどのように表示するかの設定。以下の13項目から選択する。

■ Scale To Fit
ビューの領域ぴったりに部品を拡大縮小する。縦横比は維持しない。

Scale To Fill

 

■ Aspect Fit
ビュー領域の縦横の短い方の長さと部品の長さが一致するまで縦横比を維持しながら部品を拡大縮小する。下図の灰色箇所はビューの領域。

Aspect Fit

 

■ Aspect Fill
ビュー領域の縦横の長い方の長さと部品の長さが一致するまで縦横比を維持しながら部品を拡大縮小する。ビュー領域と部品の縦横比が異なる場合、部品はビュー領域からはみ出すことになる。

Aspect Fill

 

■ Redraw
拡大縮小の方法はAspect Fillと同じ。ビュー領域の拡大縮小が行われたあとに再描画が行われる。

Redraw

 

■ Center
ビュー領域の中央に部品を配置する。

modeにcenterを設定

 

■ Top
ビュー領域内の垂直方向「上端」、水平方向「中央」に配置する。

ModeのTopを設定

 

■ Bottom
ビュー領域内の垂直方向「下端」、水平方向「中央」に配置する。

Modeにbottomを設定する

 

■ left
ビュー領域内の垂直方向「中央」、水平方向「左端」に配置する。

Modeにleftを設定する

 

■ Right
ビュー領域内の垂直方向「中央」、水平方向「右端」に配置する。

Modeにrightを設定

 

■ Top left
ビュー領域内の垂直方向「上端」、水平方向「左端」に配置する。

ModeにTop Leftを設定

 

■ Top Right
ビュー領域内の垂直方向「上端」、水平方向「右端」に配置する。

ModeにTop Rightを設定

 

■ Bottom Left
ビュー領域内の垂直方向「下端」、水平方向「左端」に配置する。

ModeにBottom Leftを設定

 

■ Bottom Right
ビュー領域内の垂直方向「下端」、水平方向「右端」に配置する。

ModeにBottom Rightを設定

 

Semantic

iOS9から追加。使い方が分かり次第ここに追記する。

 

Tag

ソースコードから部品にアクセスするための識別番号。使い方のサンプルは次の記事を参照されたし。⇒「記事

 

User Interaction Enabled

チェックを入れると、ビューをタップしたときのイベント検知が有効になる。

実際に試してみよう。以降の手順はページ前半の手順の続きである。

下図赤枠のアシスタントエディタボタンを押してViewController.swiftを開く。Ctrlキーを押しながらビューをドラック&ドロップでソースコードまで運んで吹き出しの設定画面を開く。Connectionに「Outlet」、Nameに「testView」を入力してConnectボタンを押す。これでビューをソースコードで操作できるようになった。

UIViewとソースコードのコネクションを確立する

 

ViewController.swiftを以下のように修正する。ビューがタップされたときに呼び出されるメソッドをGestureRecognizerで登録し、呼び出されたメソッドの中でビューの背景色を赤に変更している。

 

以下は実際のプレイ動画

 

Multiple Touch

チェックを入れると、部品に触れた複数の指を検知できるようになる。

ビューに触れた指の数をラベルに表示するコードを作ってみよう。Multiple Touchにチェックを入れたあと、ビューの中のラベルをクリックする。下図赤枠のTagに1を入力する。これで識別番号を使ってソースコードからラベルを操作できるようになった。

ラベルにTag番号をつける

 

View Controller.swiftを以下のように修正する。オーバーライドしているtouchesBeganメソッドはUIViewが継承しているUIResponderクラスのメソッドで、画面に指が触れたときに呼び出される。

 

以下は実際のプレイ動画。ちなみに、シュミレーターで2本の指を表現するにはOptionキーを押しながらクリックする。

 

Alpha

部品の透過度を0から1の間で設定する。0が完全に透明で見えなくなり、1は透過しない。下図は0.35に設定した結果。

Alphaに0.35を設定

 

Background

ビューの背景色

 

Tint

テキストの文字色

 

Opaque

公式リファレンスを読むと、チェックを入れると描画機能はこのビューは透過されていないと認識し、処理が最適化されてパフォーマンスが向上するといった内容が記載されている。⇒「UIViewリファレンス

また、ビューの中に透過されているものが混ざっている場合は、このチェックを外した方がが良いいうようなことが記載されているが、チェックを入れたままでも透過されるので、チェックの有無はパフォーマンスのみに影響するようだ。また、システムが提供しているクラス(UIButton, UILabel, UITableViewCellなど)でこのプロパティを設定しても影響しないといったことも書かれている。

何やらこの機能を使うには、UIViewのサブクラスを作りdrawRectメソッドをオーバーライドして独自コンテンツを作る必要があるようなことが書かれているので以下のコードを動かしてみたがOpaqueuのチェック有り無しで特に変わった様子はない。今後何か分かったら追記する。

以下はUIViewクラスのサブクラス。drawRectメソッドをオーバーライドして線を描画する処理を記述した。

 

以下は上記のサブクラスを画面に表示する処理をViewControllerクラスに記述した結果。

 

下図は実行結果
図形を描画

 

Hidden

チェックを入れると、部品が見えない状態から始まる。ソースコードからhiddenプロパティを変更すれば表示、非表示を切り替えれる。

 

Clears Graphics Context

チェックを入れると、ビュー領域内をクリアしてから描画を開始するようになる。

 

Clip Subview

チェックを入れると、ビューに追加したサブビューは親ビューの領域内のみに描画される。

試しに、以下のコードのようにビューからはみ出す位置にサブビューを追加して、Clip Subviewのチェック有無で表示の変化を確認してみよう。

 

下図はClip Subviewのチェックを外したときの実行結果。サブビューが親ビューの領域をはみ出して表示されている。

Clip Subviewのチェックを外した場合

 

下図はチェックをつけたときの実行結果。はみ出した部分が表示されなくなった。

Clip SubViewのチェックをつけた場合

 

Autoresize Subviews

チェックを入れると、ビューを拡大縮小したときに、サブビューも一緒に拡大縮小される。

 

Stretching

部品が拡大されるときにどの部分を拡大するのかを指定する。

設定項目はX、Y、Width、Heightの4項目。部品の辺の長さを1.0として0から1.0の間の数値を入力する。下図のように、部品の左上を基準点としたX座標、Y座標から、右にWidth、下にHeightに囲まれた領域が拡大対象になる。

Viewの拡大される領域

 

イメージしづらいので例題を解いてみよう。

下図はイメージビューの中に画像を表示した画面である。Modeは「Center」で、灰色部分はイメージビューの領域である。Modeを「Scale To Fill」にすると、
イメージビューの中央に画像を表示

 

下図のように画像全体が横に引き伸ばされて表示される。これを中央の茶色い線だけ横に伸ばしたい。Stretchingに設定する値を挙げよ。
画像が横に引き伸ばされて表示された

 

X座標は0.45、Y座標は0、Widthは0.1、Heightは1.0を設定すると茶色の領域のみ拡大対象になる。
回答

 

すると、下図のように表示される。
茶色い箇所のみ拡大するように設定した結果