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

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

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

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

Q&A

解決済

1回答

2631閲覧

Swift AutoLayoutをコード記述で導入する方法

torkia

総合スコア24

Swift

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

0グッド

0クリップ

投稿2018/07/21 04:04

編集2018/07/24 15:02

前提・実現したいこと

AutoLayoutのような機能をコード記述で制約をもたせたいのですが、色々なサイトを参考にしながら、NSLayoutAnchorでやるのがよさそうだと思い、サイトを参考にしてコード記述したのですが、うまくいきません。
ビルド前はコードエラーなどはでないのですが、ビルドすると白い画面になってしまいます。
コード記述ミスや、不足があるのかもしれないですが、色々やっても解決できませんでした。

わかる方がいらっしゃいましたら、原因・解決方法など教えて頂けないでしょうか。
宜しくお願い致します。

エラーメッセージ

2018-07-23 23:47:52.888494 AutoLayout[77298:11191984] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x608000284240 H:|-(0)-[UIScrollView:0x7fca1e00f400] (active, names: '|':UIView:0x7fca1d407860 )>", "<NSLayoutConstraint:0x608000284f10 H:[UIView:0x7fca1d407860]-(0)-[UIScrollView:0x7fca1e00f400] (active)>", "<NSLayoutConstraint:0x618000280fa0 'UIView-Encapsulated-Layout-Width' UIView:0x7fca1d407860.width == 414 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x608000284f10 H:[UIView:0x7fca1d407860]-(0)-[UIScrollView:0x7fca1e00f400] (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 2018-07-23 23:47:52.889410 AutoLayout[77298:11191984] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x608000284fb0 V:|-(0)-[UIScrollView:0x7fca1e00f400] (active, names: '|':UIView:0x7fca1d407860 )>", "<NSLayoutConstraint:0x6080002850a0 V:[UIView:0x7fca1d407860]-(0)-[UIScrollView:0x7fca1e00f400] (active)>", "<NSLayoutConstraint:0x6180002806e0 'UIView-Encapsulated-Layout-Height' UIView:0x7fca1d407860.height == 736 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x6080002850a0 V:[UIView:0x7fca1d407860]-(0)-[UIScrollView:0x7fca1e00f400] (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

試したこと

iPhone7のサイズで作成して、シュミレーターはiPhone7Plusのサイズで試しています。
サンプルコードでは、scrollViewにNSLayoutAnchorを施しています。
scrollViewにのせているUI部品なども連動してサイズを変更させたいのですが、できませんでした。それは無理なのでしょうか?
Storyboardで制約をもたせて、コードとOutlet接続してから、その他の詳細はコード記述で行う方法をやってみたのですが、scrollViewのみ制約が施され、その他のscrollViewにaddSubviewしている部品などはそのままでした。
コード記述でNSLayoutConstraintも試して見たのですが、同じくscrollViewのみ制約が施されるだけでした。

view, label, button などそれぞれに制約を施すコードを記述する必要があるのでしょうか?

該当のソースコード

// [使用Version Swift3] import UIKit class ViewController: UIViewController,UIScrollViewDelegate { let scrollView = UIScrollView() var scrollViewContentHeight:CGFloat = 667 var labelsMaxY: CGFloat = 100 let titleLabel = UILabel() var labels = [UILabel]() override func viewDidLoad() { super.viewDidLoad() scrollView.frame.size = CGSize(width: 375, height: 667) scrollView.contentSize = CGSize(width: 375, height: scrollViewContentHeight) scrollView.bounces = false scrollView.indicatorStyle = .default scrollView.scrollIndicatorInsets = UIEdgeInsets(top: 10, left: 5, bottom: 10, right: 5) scrollView.delegate = self scrollView.backgroundColor = UIColor.yellow scrollView.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview(scrollView) // NSLayoutAnchor scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true scrollView.leadingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true scrollView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true scrollView.topAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true // タイトルラベル titleLabel.frame = CGRect(x: 20, y: 20, width: 335, height: 20) titleLabel.text = "ラベル" titleLabel.backgroundColor = .magenta scrollView.addSubview(titleLabel) // ラベル量産 for index in 0..<20 { let label = UILabel() label.frame = CGRect(x: 20, y: 100 + (40 * index), width: 335, height: 40) label.backgroundColor = UIColor.lightGray label.text = "test(index + 1)" if index % 2 == 0 {label.backgroundColor = UIColor.gray} labels.append(label) scrollView.addSubview(label) } // 表示されてるラベルのmaxYを取得 var sum: CGFloat = 100 for index in 0..<labels.count { if labels[index].isHidden == false { let height = labels[index].frame.height sum += height labelsMaxY = sum } } // scrollViewContentHeightの値を再設定 scrollViewContentHeight = labelsMaxY + 100 scrollView.contentSize.height = scrollViewContentHeight } //viewDidLoadを閉じる }

■ iPhone7Plusでビルド
NSAnchorを記述した場合 NSAnchorを記述しない場合 Storyboardで制約を施した場合
NSAnchorを記述しない場合 NSAnchorを記述した場合 Storyboardで制約を施した場合

■ iPhone7でビルド
通常時(理想図)
iPhone7でRun

補足情報(FW/ツールのバージョンなど)

Swift3

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

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

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

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

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

guest

回答1

0

ベストアンサー

とりあえず該当コードでエラーが発生して白い画面になってしまうのは
制約の付け方で解釈できない部分があるためエラーで表示できなくなってしまっています。
該当箇所は以下です。
やりたいことはおそらく、leadingAnchor、trailingAnchor、topAnchor、bottomAnchorを合わせることだと
思います。書き換えたところ私の環境では画面が表示されましたのでご確認をお願いいたします。

// NSLayoutAnchor scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true // leadingAnchorに再度制約をつけようとしていた。 scrollView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true // topAnchorに再度制約をつけようとしていた。

今のコードのままの状態だと「Storyboardで制約を施した場合」と同じなりますが
今回の質問に関してはエラーの原因についてだけで大丈夫でしょうか?

投稿2018/07/24 06:12

razuma

総合スコア1313

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

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

torkia

2018/07/24 06:32

ご回答ありがとうございます。 ご指摘頂きましたNSLayoutAnchorでの記述を書き換えたら画面表示できるようになりました。 丁寧な説明ありがとうございました。 >> エラーの原因についてだけで大丈夫でしょうか? できれば、「試したこと」の後半部分に書いている内容(scrollViewにaddSubviewしているUI部品全てを同じように制約を持たせたい)についても教えて頂ければ、とても助かります。
razuma

2018/07/24 06:55

今のサンプルコードだと全てコード状で部品が作成されており、scrollViewにself.viewとサイズが合うような制約のみしか書かれていない状態だと思いますが、部品も連動させて変更したいとは具体的にどのようなことになりますでしょうか? 例えば今回のUILabelが配置された例で言うと、storyboard上ではscrollViewのtailingとUILabelのtailingを合わせるような制約をつけていた時にscrollView.trailingAnchorを変更して画面いっぱいに表示されるようにしてもUILabelのtailingの位置はそのまま、のようなことでしょうか?(試してみていないのでそうなるかはわかりません) 質問が回答済みになってしまって他の回答者が現れなくなるかもしれないのと、ちょっとすぐに私が回答できるかもわからないので質問を別起票していただいた方が回答が得られるかもしれません。(具体例をあげていただけるとわかりやすいと思います、storyboard上ではこのような制約をつけていて、画面上からはこの制約をしたときにどうなって欲しいか)
torkia

2018/07/24 07:19

ご回答ありがとうございます。 ラベルなどをのせているviewがNSAnchorで制約を施されれば一緒に伸びてくれるのだと(画面サイズ4.7inchと5.5inchでのズレ)、最初は思っていたのですが、そのようにはならず。コード記述に間違いがあるのか、それぞれ個別に制約のコードを記述しなければいけないのか?というのがわからなかったのですが、質問内容を整理して別項目であげてみます。 度々のご回答ありがとうございました。お手数をおかけ致しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問