LoginSignup
14
8

More than 5 years have passed since last update.

サイズ可変の画像の上にAutoLayoutでうまいことテキストを置く

Last updated at Posted at 2017-11-21

nahuda.png

お題

  1. このような名札.pngの上にユーザーが入力したテキストを配置するにはどうすれば良いか:thinking:
  2. 画像のサイズは可変とする

実装のコツ

AutoLayoutの Multiplier を使うことで、画像サイズからパーセント指定で位置を指定することができます

指定の仕方

まず配置するUILabelの準備

  1. 名札からはみ出さないように、幅に合わせてfontサイズを調整してくれる adjustsFontSizeToFitWidthtrue
  2. minimumScaleFactor で最小フォントサイズを指定します
var nameLabel: UILabel = {
    let lb = UILabel()
    lb.text = "きんにくひろし"
    lb.numberOfLines = 1
    lb.font = UIFont.boldSystemFont(ofSize: 48)
    lb.adjustsFontSizeToFitWidth = true
    lb.minimumScaleFactor = 8 / lb.font.pointSize
    return lb
}()

AutoLayoutの指定

translatesAutoresizingMaskIntoConstraintsfalse
NSLayoutConstraint を使ってLayoutします
multiplier を使うことで、パーセント指定で親要素からの相対的な位置を指定することができます。

※この際、left margin なら親要素の right margin を対象にすることで、指定が効きます。
left margin を対象に指定してしまうと、起点0なので思うようにレイアウトが効きません。

※上下左右マージンを指定しないと、テキストがadjustしてくれません

nameLabel.translatesAutoresizingMaskIntoConstraints = false

// 名前LabelのAutoLayout

imageView.addConstraints([
    // top
    NSLayoutConstraint(
        item: nameLabel,
        attribute: .top,
        relatedBy: .equal,
        toItem: imageView,
        attribute: .bottom,
        multiplier: 0.65,
        constant: 0
    ),
    // bottom
    NSLayoutConstraint(
        item: nameLabel,
        attribute: .bottom,
        relatedBy: .equal,
        toItem: imageView,
        attribute: .bottom,
        multiplier: 0.85,
        constant: 0
    ),
    // left
    NSLayoutConstraint(
        item: nameLabel,
        attribute: .left,
        relatedBy: .equal,
        toItem: imageView,
        attribute: .right,
        multiplier: 0.23,
        constant: 0
    ),
    // right
    NSLayoutConstraint(
        item: nameLabel,
        attribute: .right,
        relatedBy: .equal,
        toItem: imageView,
        attribute: .right,
        multiplier: 0.7,
        constant: 0
    )
])

完成

ベースの画像サイズが可変しても、綺麗にテキストが収まっています
CustomViewにしておくと、複数画面で利用するとき便利でしょう

Landscape Portrait

Multiplierの値をどう決めるか?

Zeplinで簡単に取れます。
Alt を押しながら確認したいmarginあたりにカーソルを近づけると親要素からの
marginを%表示できるので、それを使います。

zeplin.png

(Sketchでもできるかも..少し触っただけだと%表示できなかった)

おまけ:SnapKitを使った実装

41行 -> 6行で書けました:innocent: 便利

// 名前LabelのAutoLayout
nameLabel.snp.makeConstraints { (make) in
    make.top.equalTo(imageView.snp.bottom).multipliedBy(0.65)
    make.bottom.equalTo(imageView.snp.bottom).multipliedBy(0.85)
    make.left.equalTo(imageView.snp.right).multipliedBy(0.23)
    make.right.equalTo(imageView.snp.right).multipliedBy(0.7)
}
14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8