質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1247閲覧

ラベルの高さを同じにしたのに違ってきてしまう。

vitoyaokatsu

総合スコア12

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/10/31 06:45

イメージ説明
以下のようにラベルを配置し制約をかけました。yearLabelが他のラベルより低くなるのが何故かわかりません。お教えください。

Swift

1// IF components layout 2 lazy var yearLabel: UILabel = { 3 let label = UILabel() 4 let labelWidth = NSLayoutConstraint() 5 label.frame = CGRect(x:viewWidth * 0.0531, y:viewHeight * 0.1138, width:114, height:50)//sennsei ni kiku! 6 label.font = UIFont.systemFont(ofSize: dateFontSize) 7 label.textAlignment = .left 8 label.textColor = .white 9 label.text = getDateYearText(isThisYear: true) 10 label.backgroundColor = .gray //remove 11// let frame = CGSizeMake(250, CGFloat.max) 12 // 文字列の幅に調節したサイズを取得 13// let rect = labelWidth.sizeThatFits(frame) 14 // UILabel の width の制約に、調節済みの width を設定 15// Label.constant = rect.width 16// let rect = label.sizeThatFits(label) 17// // UILabel の width の制約に、調節済みの width を設定 18// label.constant = rect.width 19// label.adjustsFontSizeToFitWidth = true 20 return label 21 22 }() 23 24 lazy var dot1: UILabel = { 25 let label = UILabel() 26 label.frame = CGRect(x:viewWidth * 0.320, y:viewHeight * 0.1138, width:10, height:50) 27 label.font = UIFont.systemFont(ofSize: dateFontSize) 28 label.textAlignment = .left 29 label.textColor = .white 30 label.text = "." 31 label.backgroundColor = .black //remove 32 return label 33 }() 34 35 lazy var monthLabel: UILabel = { 36 let label = UILabel() 37 label.frame = CGRect(x:viewWidth * 0.325, y:viewHeight * 0.1138, width:75, height:50) 38 label.font = UIFont.systemFont(ofSize: dateFontSize) 39 label.textAlignment = NSTextAlignment.right 40 label.textColor = UIColor.white 41 label.text = getDateMonthText(isThisMonth: true) 42 label.backgroundColor = .gray //remove 43 return label 44 }() 45 46 lazy var dot2: UILabel = { 47 let label = UILabel() 48 label.frame = CGRect(x:viewWidth * 0.50, y:viewHeight * 0.1138, width:10, height:50) 49 label.font = UIFont.systemFont(ofSize: dateFontSize) 50 label.textAlignment = .left 51 label.textColor = .white 52 label.text = "." 53 label.backgroundColor = .black //remove 54 return label 55 }() 56 57 lazy var dayLabel: UILabel = { 58 let label = UILabel() 59 label.frame = CGRect(x:viewWidth * 0.53, y:viewHeight * 0.1138, width:60, height:50) 60 label.font = UIFont.systemFont(ofSize: dateFontSize) 61 label.textAlignment = NSTextAlignment.right 62 label.textColor = UIColor.white 63 label.text = getDateDayText(isToday: true) 64 label.backgroundColor = .gray //remove 65 return label 66 67 }()コード

中略

Swift

1view.addSubview(yearLabel) 2 view.addSubview(monthLabel) 3 view.addSubview(dayLabel) 4 view.addSubview(whatDayLabel) 5 view.addSubview(dot1) 6 view.addSubview(dot2) 7// view.addSubview(todoTable) 8 view.addSubview(table) 9 view.addSubview(todayButton) 10// view.addSubview(moveToCalenderButton) 11 view.addSubview(settingButton) 12// view.addSubview(nextDayButton) 13// view.addSubview(theDayBefore) 14 dot1.translatesAutoresizingMaskIntoConstraints = false 15 monthLabel.translatesAutoresizingMaskIntoConstraints = false 16 dot2.translatesAutoresizingMaskIntoConstraints = false 17 dayLabel.translatesAutoresizingMaskIntoConstraints = false 18// dot1.bottomAnchor.constraint(equalTo: yearLabel.bottomAnchor).isActive = true 19// dot1.leadingAnchor.constraint(equalTo: yearLabel.trailingAnchor,constant: 20).isActive = true 20 dot1.bottomAnchor.constraint(equalTo: yearLabel.bottomAnchor).isActive = true 21 dot1.leadingAnchor.constraint(equalTo: yearLabel.trailingAnchor,constant: 0).isActive = true 22 monthLabel.bottomAnchor.constraint(equalTo: dot1.bottomAnchor).isActive = true 23 monthLabel.leadingAnchor.constraint(equalTo: dot1.trailingAnchor,constant: 5).isActive = true 24 dot2.bottomAnchor.constraint(equalTo: monthLabel.bottomAnchor).isActive = true 25 dot2.leadingAnchor.constraint(equalTo: monthLabel.trailingAnchor,constant: 0).isActive = true 26 dayLabel.bottomAnchor.constraint(equalTo: dot2.bottomAnchor).isActive = true 27 dayLabel.leadingAnchor.constraint(equalTo: dot2.trailingAnchor,constant: 5).isActive = true 28コード

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

translatesAutoresizingMaskIntoConstraintsfalse にすることによって、その UI 部品に設定されていた固定値の frame は無視され、テキストにあったサイズが自動的に設定されるようになっています。

なので、yearlabel 以外はテキストの上下に対し、自動的な空白が適用されるよう、AutoLayout によって適切な空白が挿入されるため、高さの違いが生じているかと思います。

もちろん、幅に対しても自動的に適用されます。

解決策はコンテンツをどのように展開させた以下によって異なってくるかと思いますが、一つは全てのラベルに対し、高さ、幅の制約をつける方法かと思います。

たとえば、

Swift

1 dot1.heightAnchor.constraint(equalToConstant: 50).isActive = true 2 monthLabel.heightAnchor.constraint(equalToConstant:50).isActive = true 3 dot2.heightAnchor.constraint(equalToConstant: 50).isActive = true 4 dayLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true

みたいな制約を追加すれば、とりあえず全ての高さを 50 ピクセル固定にできますので、先頭のラベルと同じ高さにすることは可能です(ただし、根本的な解決とは言えないかと思いますので、その点はご注意ください)。

##2020年11月2日追記

Swift

1yearLabel.translatesAutoresizingMaskIntoConstraints = false

とした場合、おそらくラベルは消えたのではなく、左上を原点として再配置されたのだと思います。ただし、私のコードはご提示いただいたコードをもとに再現しただけなので、質問者さんの環境とは異なっている可能性がありますし、設定次第では描画範囲内から消えてしまった可能性もあります。

シミュレータで実行中に「View Hierarchy」のボタンを押すと、その時に表示されているビューの構造を視覚的に見ることが可能となります(下図左下のボタン)。

イメージ説明

このとき、右上や左側ペインに表示されたUI部品の部分に紫色の警告が出ますが、その内容は [Position is ambiguous] 、つまり座標が曖昧だということです。

5つのラベル全てに出ていますが、おそらくほかの4つのラベルの基準となる yearLabel の座標をきちんと設定すれば、のこり4つの制約に対する曖昧さは解消すると思います。

先にも回答しました通り、

Swift

1yearLabel.translatesAutoresizingMaskIntoConstraints = false

と記述すると、frameなどに値を設定しても、その値は適切に設定されません。Autolayout で計算された値が優先されるからだと思います(一方、AutoLayout の結果として framebounce の値は参照可能です)。

つまり、一度 AutoLayout を使うと決めたら、全てを「制約」として設定しなければならないと考えています。

yearLabel を AutoLayout で設定するとなると、CGRect で設定した座標も無効になりますので、再度制約をかけるなどして部品の相対的な位置を決める必要があるのではないでしょうか。

きちんと計算していないので間違っている可能性もありますが、たとえばこのような感じで yearLabel の制約を設定すると解決するかと思います。

Swift

1 yearLabel.translatesAutoresizingMaskIntoConstraints = false 2 3 yearLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: view.frame.height * 0.1138).isActive = true 4 yearLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: view.frame.width * 0.0531).isActive = true 5 yearLabel.heightAnchor.constraint(equalToConstant: 50).isActive = true

投稿2020/10/31 23:54

編集2020/11/02 08:07
TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vitoyaokatsu

2020/11/01 22:43

めちゃくちゃ助かりました。ありがとうございました。 追加で質問があります。 yearLabel.translatesAutoresizingMaskIntoConstraints = falseを追加したところ dayLabelまでの全てが表示されなくなりました。 再度削除し、教えていただいたコンストレインとを追記したところ 正常に高さが揃いました。 yearLabelのtranslatesAutoresizingMaskIntoConstraints をfalseにしたために yaerLabelの表示される座標が自動的にどこかに設定されてしまったのでしょうか? label.frame = CGRect(x:viewWidth * 0.0531, y:viewHeight * 0.1138, width:114, height:50)の座標の意味がなくなったような気がします。 もう少しこの辺りをお教えいただけるとありがたいです。 たとえば基準となる最左上のyearLableは絶対値で設定し yearLabelに揃えるドットやマンス・・・・にはyearLabel相対的にするという 考え方なのでしょうか??? お教えくださるとありがたいです。
TsukubaDepot

2020/11/01 23:33

label.frame ... の設定は、translatesAutoresizingMaskIntoConstraints を false にすることで無効になります(これは先の回答に書いた通りです)。 絶対値で指定したいということであれば、全てご自身で frame の値を計算し、コードとして記述する必要があります。 一方、Autolayout を使うのであれば、Autolayout に関連する全ての部品を Autolayout で設定する必要があります(もちろん、併用することも可能だと思いますが、良く理解した上で併用する必要があると思います)。 Autolayout をコードで記述するのも、StoryBoard で設定するのも本質的には何も変わらないと思っています。 なので、もしコードで書くのが良く理解できていないということであれば、まずは直感的で分かりやすい StoryBoard で設定を行い、制約の考え方を把握した上でコードに落とし込んだほうがわかりやすいのではないでしょうか。 参考になるコードは回答本文に追記しました。
vitoyaokatsu

2020/11/02 07:46

大変参考になりました。そして、よくわかりました。また、ものすごく丁寧に、またいろんなことを試してくださって、感謝としかいいようがありません。私は今後のことを考えてコードで書くようにしています。ご回答いただいたことで、心折れずに前に進めます。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問