
どうも。暑い日が続きますが「Cool bed.」してますでしょうか。
週刊「LUV CAN SAVE Uアプリを作る」第2号、今回は画面に表示する2つの画像を用意するところまで作っていきます。
Contents
今回やること
まずは前回まとめたアプリの機能一覧をおさらい。
- 初期状態で、2つの画像が表示されている
- 男側の画像の位置とサイズは以下の通り
- 初期位置は画面の中心からやや下
- 幅は画面の2/3ほど
- 高さは画面の1/3より少し大きいくらい
- 女側の画像の位置とサイズは以下の通り
- 拡大後のサイズを基準とする(初期状態は縮小)
- サイズは男側の画像と同じ
- 縮小状態のサイズは元の2/3
- 画面の右下角に、少し余白を置いて配置する
- 画像はやや透過気味
- 水色の線で縁取られている
- 画像の背景は紫色
- 男側の画像の方が手前に表示されている
- 男側の画像の位置とサイズは以下の通り
- 男側の画像を上にフリックすると、画像が移動する
- 0.2秒ほどでアニメーションする
- 移動先は画面の左上角
- 逆の動作も用意する(下にフリックしたら下に動く)
- 女側の画像をタップすると、画像が拡大する
- タップしたら一瞬で拡大させる
- 逆の動作も用意する(縮小させる)
- 画像が縮小中のときは拡大、拡大中のときは縮小する
今回は赤文字で示した部分、つまり2つの画像を表示させるところまで進めていきます。
2つの画像を配置する
表示する画像を用意する
まずは実際に表示する2つの画像ファイルを用意しましょう。
いらすとや様から以下の2つの素材を拝借。
わかりやすいファイル名に変更して、プロジェクトに追加。
男側の画像を配置
最初にViewControllerクラス内でUIImageView型の定数を宣言。今回は関係ないですが、次回以降いろいろな場所でこの画像を参照するのでここで宣言します。
1 2 3 4 5 6 7 8 |
import UIKit class ViewController: UIViewController { // 男側の画像 let pictureBoy = UIImageView() // 略 |
定数を宣言したら、viewDidLoad()内で詳細を書いていきます。
まず、この先よく使う変数として「ビュー(画面)の幅」と「ビューの高さ」を定数として用意。
1 2 3 |
// ビューの幅と高さ(よく使うので) let viewWidth = view.bounds.width let viewHeight = view.bounds.height |
pictureBoyに実際に表示する画像を指定します。「LuvCan_boy.png」の部分は、最初に用意したファイル名に合わせてください。
1 2 |
// 画像を指定 pictureBoy.image = UIImage(named: "LuvCan_boy.png") |
次に、表示する画像の幅と高さを指定。幅はビューの2/3、高さはビューの1/3より少し大きく。
ちなみにこの指定は「座標(0,0)を起点にして、右にwidth・下にheightぶん広げた枠を作る」という意味です。位置はこの次にちゃんと指定するのでご安心を。
1 2 |
// 幅と高さを指定(座標(0,0)に仮置きする) pictureBoy.bounds = CGRect(x: 0, y: 0, width: viewWidth * 2/3, height: viewHeight * 1/3 + 30) |
大きさが決まったので、次は画像を配置する場所。画像の中心座標を「ビューの中心座標から少し下にずらした点」に設定します。
1 2 |
// 中心座標はビューの中心からやや下 pictureBoy.center = CGPoint(x: view.center.x, y: view.center.y + 40) |
このまま表示しようとすると、画像が枠にぴったり合うように伸び縮みしてしまう。そこで、画像の表示方法を「縦横比を維持しつつ、枠にフィットさせる」というモードに設定。
1 2 |
// 画像の表示モードを指定する pictureBoy.contentMode = .scaleAspectFit |
あとは用意したUIImageViewをビューに表示するだけ。これを忘れて「表示されない!?」となるのはよくあること。
1 2 |
// ビューに表示 view.addSubview(pictureBoy) |
ここまででコードはこんな感じになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import UIKit class ViewController: UIViewController { // 男側の画像 let pictureBoy = UIImageView() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // ビューの幅と高さ(よく使うので) let viewWidth = view.bounds.width let viewHeight = view.bounds.height // 男側の画面を作る // 画像を指定 pictureBoy.image = UIImage(named: "LuvCan_boy.png") // 幅と高さを指定(座標(0,0)に仮置きする) pictureBoy.bounds = CGRect(x: 0, y: 0, width: viewWidth * 2/3, height: viewHeight * 1/3 + 30) // 中心座標はビューの中心からやや下 pictureBoy.center = CGPoint(x: view.center.x, y: view.center.y + 40) // 画像の表示モードを指定する pictureBoy.contentMode = .scaleAspectFit // ビューに表示 view.addSubview(pictureBoy) } |
女側の画像を配置
まずは男側の画像と同様に、ViewControllerクラス内でUIImageView型の定数を宣言するところから。
1 2 3 4 5 6 7 8 9 10 |
import UIKit class ViewController: UIViewController { // 男側の画像 let pictureBoy = UIImageView() // 女側の画像 let pictureGirl = UIImageView() // 略 |
以下、viewDidLoad()内で細かい設定。最初に表示する画像のファイル名を指定します。
1 2 |
// 画像を指定 pictureGirl.image = UIImage(named: "LuvCan_girl.png") |
画像の大きさは拡大後のサイズを基準にします。サイズは男側の画像と同じなので、それを参照させましょう。
1 2 |
// 幅と高さを指定(拡大後の大きさを指定 つまり男側の画面と同じ) pictureGirl.bounds = pictureBoy.bounds |
ビューの右下に40pxの余白ができるように、中心座標を設定。
1 2 3 |
// 中心座標を指定 // x:ビューの幅 - 拡大後のimageViewの幅/2 - 40, y:ビューの高さ - 拡大後のimageViewの高さ/2 - 40 pictureGirl.center = CGPoint(x: viewWidth - pictureGirl.bounds.width / 2 - 40, y: viewHeight - pictureGirl.bounds.height / 2 - 40) |
男側と同様に、画像の表示モードを設定。
1 2 |
// 画像の表示モードを指定する pictureGirl.contentMode = .scaleAspectFit |
初期表示は画像が縮小した状態なので、CGAffineTransformで変形。
1 2 |
// 初期状態で縮小させる pictureGirl.transform = CGAffineTransform(scaleX: 2/3, y: 2/3) |
最後に、ビューに画像を表示。
1 2 |
// ビューに表示 view.addSubview(pictureGirl) |
ここまでのコードをまとめましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import UIKit class ViewController: UIViewController { // 男側の画像 let pictureBoy = UIImageView() // 女側の画像 let pictureGirl = UIImageView() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // ビューの幅と高さ(よく使うので) let viewWidth = view.bounds.width let viewHeight = view.bounds.height // 男側の画面を作る // 画像を指定 pictureBoy.image = UIImage(named: "LuvCan_boy.png") // 幅と高さを指定(座標(0,0)に仮置きする) pictureBoy.bounds = CGRect(x: 0, y: 0, width: viewWidth * 2/3, height: viewHeight * 1/3 + 30) // 中心座標はビューの中心からやや下 pictureBoy.center = CGPoint(x: view.center.x, y: view.center.y + 40) // 画像の表示モードを指定する pictureBoy.contentMode = .scaleAspectFit // ビューに表示 view.addSubview(pictureBoy) // 女側の画面を作る // 画像を指定 pictureGirl.image = UIImage(named: "LuvCan_girl.png") // 幅と高さを指定(拡大後の大きさを指定 つまり男側の画面と同じ) pictureGirl.bounds = pictureBoy.bounds // 中心座標を指定 // x:ビューの幅 - 拡大後のimageViewの幅/2 - 40, y:ビューの高さ - 拡大後のimageViewの高さ/2 - 40 pictureGirl.center = CGPoint(x: viewWidth - pictureGirl.bounds.width / 2 - 40, y: viewHeight - pictureGirl.bounds.height / 2 - 40) // 画像の表示モードを指定する pictureGirl.contentMode = .scaleAspectFit // 初期状態で縮小させる pictureGirl.transform = CGAffineTransform(scaleX: 2/3, y: 2/3) // ビューに表示 view.addSubview(pictureGirl) } |
画像の細かい調整
画像を不透明度を調節する
UIImageViewのalphaプロパティで、画像の不透明度を設定できます。1.0が不透明度100%で、0.0が不透明度0%。
1 2 3 |
// ビューを透過させる(不透明率80%) pictureBoy.alpha = 0.8 pictureGirl.alpha = 0.8 |
画像を水色の線でふち取る
layer.borderColorで枠線の色、layer.borderWidthで枠線の太さを指定します。
1 2 3 4 5 6 |
// 画面に枠を作る pictureBoy.layer.borderColor = UIColor(red: 0.5, green: 0.7, blue: 0.8, alpha: 1.0).cgColor pictureBoy.layer.borderWidth = 5 pictureGirl.layer.borderColor = UIColor(red: 0.5, green: 0.7, blue: 0.8, alpha: 1.0).cgColor pictureGirl.layer.borderWidth = 5 |
画像の透過部分(背景色)を紫色にする
backgroundColorプロパティで背景色を指定できます。
1 2 3 |
// 背景の色を指定する pictureBoy.backgroundColor = UIColor(red: 0.4, green: 0.4, blue: 0.6, alpha: 0.5) pictureGirl.backgroundColor = UIColor(red: 0.4, green: 0.4, blue: 0.6, alpha: 0.5) |
男側の画像を手前に表示する
明示的に「男側の画像の方が手前」にするために、viewのbringSubviewメソッドを使用します。手前に持っていきたいビューを「toFront」に指定。
1 2 |
// 男側の画面が上に乗るようにする view.bringSubview(toFront: pictureBoy) |
ここまでのコード
ここまでの内容で、冒頭に示した画像のような表示ができるはずです。試しに動かしてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
import UIKit class ViewController: UIViewController { // 男側の画像 let pictureBoy = UIImageView() // 女側の画像 let pictureGirl = UIImageView() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // ビューの幅と高さ(よく使うので) let viewWidth = view.bounds.width let viewHeight = view.bounds.height // 男側の画面を作る // 画像を指定 pictureBoy.image = UIImage(named: "LuvCan_boy.png") // 幅と高さを指定(座標(0,0)に仮置きする) pictureBoy.bounds = CGRect(x: 0, y: 0, width: viewWidth * 2/3, height: viewHeight * 1/3 + 30) // 中心座標はビューの中心からやや下 pictureBoy.center = CGPoint(x: view.center.x, y: view.center.y + 40) // 画像の表示モードを指定する pictureBoy.contentMode = .scaleAspectFit // ビューを透過させる(不透明率80%) pictureBoy.alpha = 0.8 // 画面に枠を作る pictureBoy.layer.borderColor = UIColor(red: 0.5, green: 0.7, blue: 0.8, alpha: 1.0).cgColor pictureBoy.layer.borderWidth = 5 // 背景の色を指定する pictureBoy.backgroundColor = UIColor(red: 0.4, green: 0.4, blue: 0.6, alpha: 0.5) // ビューに表示 view.addSubview(pictureBoy) // 女側の画面を作る // 画像を指定 pictureGirl.image = UIImage(named: "LuvCan_girl.png") // 幅と高さを指定(拡大後の大きさを指定 つまり男側の画面と同じ) pictureGirl.bounds = pictureBoy.bounds // 中心座標を指定 // x:ビューの幅 - 拡大後のimageViewの幅/2 - 40, y:ビューの高さ - 拡大後のimageViewの高さ/2 - 40 pictureGirl.center = CGPoint(x: viewWidth - pictureGirl.bounds.width / 2 - 40, y: viewHeight - pictureGirl.bounds.height / 2 - 40) // 画像の表示モードを指定する pictureGirl.contentMode = .scaleAspectFit // 初期状態で縮小させる pictureGirl.transform = CGAffineTransform(scaleX: 2/3, y: 2/3) // ビューを透過させる(不透明率80%) pictureGirl.alpha = 0.8 // 画面に枠を作る pictureGirl.layer.borderColor = UIColor(red: 0.5, green: 0.7, blue: 0.8, alpha: 1.0).cgColor pictureGirl.layer.borderWidth = 5 // 背景の色を指定する pictureGirl.backgroundColor = UIColor(red: 0.4, green: 0.4, blue: 0.6, alpha: 0.5) // ビューに表示 view.addSubview(pictureGirl) // 男側の画面が上に乗るようにする view.bringSubview(toFront: pictureBoy) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
次回予告
第3号では、指で画像を動かす処理を実装していきます。これでアプリはほぼ完成になります! お楽しみにー。
このシリーズの記事
- 週刊「LUV CAN SAVE Uアプリを作る」創刊号 〜アプリの仕様を決める
- 週刊「LUV CAN SAVE Uアプリを作る」第2号 〜画像を配置する
- 週刊「LUV CAN SAVE Uアプリを作る」第3号 〜画像を指で動かす