LoginSignup
1
3

More than 5 years have passed since last update.

【swift4】【NSLayoutAnchor】 設定の順番とtopAnchorの%指定方法

Posted at

少し、突っかかって悩んだのと、メモとして残しておきたいのでまとめておきます。

Auto Layoutをコードで書いてみた

設定出来るConstraintsとか、translatesAutoresizingMaskIntoConstraintsとは何かについては基本的にこの記事が詳しかったので、省きます。

フレキシブルにラベル等を表示したい

  • View上に、フレキシブルにラベルなんかを表示したい。(要らないときは表示したくない、スケーリングもしたい)

 要らないときは、という部分についてはコードで生成すれば解決、ということで特に迷いませんでした。
 スケーリングについてはEqualHeightsとかその手のものを利用してストーリーボード上で既に出来ていましたし、NSLayoutAnchorにすぐに辿り着いたのでそこらへんもおおよそ問題ありませんでした。
 ただ、幾つか引っかかったのが、Constraints設定とViewへのオブジェクト追加の順番と、上端や左端の%値での設定、Autorisizingのフラグ設定でした。

生成〜設定の順序

サンプル

    // ラベルを生成
    let label = UILabel()
    label.text = "やらないか"

    // fontのオートシュリンクの設定
    label.adjustsFontSizeToFitWidth = true
    label.minimumScaleFactor = 0.3

    // font
    if let customFont = UIFont(name: "Bradley Hand", size: UIFont.labelFontSize) {
        label.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: customFont)
    } else {
        label.font = UIFont.preferredFont(forTextStyle: .body)
    }

    // viewにラベルを追加
    // constraintsよりも前に追加する必要がある
    view.addSubview(labNone)

    // AutoresizingMaskの設定値を使うとバッティングするのでフラグをfalseにする
    label.translatesAutoresizingMaskIntoConstraints = false
    // constraints
    // 大本のViewとX軸中心合わせ
    label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    // 大本のViewとY軸合わせ。
    // 1/2を3/8にしたい(上げたい)
    let pos = (view.frame.size.height / 8.0) * -1
    label.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: pos).isActive = true
    // 大本のViewと幅合わせ。view比60%で設定
    label.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.6).isActive = true
    // 大本のViewと高さ合わせ。view比8%で設定
    label.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.08).isActive = true

  • ラベル等の生成
  • フォント等の設定
  • Viewに登録
  • translatesAutoresizingMaskIntoConstraintsをfalse
  • Constraintsの設定

の順番で。
 Viewに登録してからConstraintsを設定しないと落ちますし、translatesAutoresizingMaskIntoConstraintsフラグがデフォルトのtrueのままだと競合して表示できません。
なんでエラーが出るの?Constraints揃ってない??とか小一時間悩みました。

translatesAutoresizingMaskIntoConstraintsについてはViewの登録の前後どちらかでないと駄目なのかでどうかまでは見てません。

位置の設定で固定値を使いたくない

デバイスごとの位置調整の問題でViewやラベルのサイズなんかはViewとEqualHeightなんかを駆使してmultipliterで%指定したりするわけですが、leadingAnchor(左端)や、topAnchor(上端)を設定しようと思ってAutoLayoutのUIでやろうとすると固定値を入れる羽目になるわけで。
 コードで打てばなんとかなるのかな、と思いましたが、viewのheightAnchorやwidthAnchorからすぐに値を取り出せなくて少し悩みました。

    // 大本のViewとY軸中心合わせ.
    // 1/2を3/8にしたい(上げたい)
    let pos = (view.frame.size.height / 8.0) * -1
    label.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: pos).isActive = true

上のソースのここでしれっとやってるのですが、
view.frame.size.heightでviewのフレームの高さの数値が取れるので、それで計算してしまえばいけます。widthもあるよ!

topAnchor、leadingAnchorの場合はこんな感じ、です。

    // Viewの上端から10%の位置を指定
    let posTop = view.frame.size.height * 0.1
    label.topAnchor.constraint(equalTo: view.topAnchor, constant: posTop).isActive = true
    // viewの幅の5%の位置を指定
    let posLead = view.frame.size.width * 0.05
    label.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: posLead).isActive = true
1
3
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
1
3