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

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

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

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

Q&A

解決済

1回答

920閲覧

ScrollViewにAutoLayoutが付けられません…

OBN

総合スコア16

Swift

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

0グッド

0クリップ

投稿2019/06/23 13:38

編集2019/07/01 01:39

以下のコードのScrollViewにAutoLayoutをつけて多画面に対応させたいのですが、通常のViewと同様に制約をつけても上手くいきません。Webで色々調べたのですが、自分の書いたコードのケースに当てはまるものが無く困っています。ご教授頂けると嬉しいです!

StoryBoardは元々のViewの上にScrollViewとButtonが載っている状態でLabelはコードで生成しています。
View as iPhoneXR以外でbuildすると大きさが合いません…

Swift

1**TutorialViewController.Swift** 2 3import UIkit 4import Lottie 5 6class TutorialViewController: UIViewController { 7 8 var onboardStringArray = ["a","i","u","e","o","あ","い","う"] 9 10 11 @IBOutlet var scrollView: UIScrollView! 12 13 var animationArray = ["onboard1","onboard2","onboard3","onboard4","onboard5","onboard6","onboard7","onboard8"] 14 15 16 17 override func viewDidLoad() { 18 super.viewDidLoad() 19 20 scrollView.isPagingEnabled = true 21 22 setUpScroll() 23 24 for i in 0...7{ 25 26 let animationView = AnimationView() 27 let animation = Animation.named(animationArray[i]) 28 animationView.frame = CGRect(x: CGFloat(i) * self.view.frame.size.width, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.width) 29 30 animationView.animation = animation 31 animationView.contentMode = .scaleAspectFit 32 animationView.loopMode = .loop 33 animationView.play() 34 scrollView.addSubview(animationView) 35 36 } 37 38 } 39 40 func setUpScroll(){ 41 42 scrollView.contentSize = CGSize(width: view.frame.size.width * 8, height: view.frame.size.height) 43 44 for i in 0...7{ 45 46 let onboardLabel = UILabel(frame: CGRect(x: CGFloat(i) * self.view.frame.size.width, y: self.view.frame.size.height/3, width: scrollView.frame.size.width, height:scrollView.frame.size.height)) 47 48 onboardLabel.font = UIFont.boldSystemFont(ofSize: 15.0) 49 onboardLabel.textAlignment = .center 50 onboardLabel.text = onboardStringArray[i] 51 scrollView.addSubview(onboardLabel) 52 53 54 } 55 56 } 57 58}

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

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

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

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

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

nakasho_dev

2019/06/24 11:14

質問するときのヒント( https://teratail.com/help/question-tips )を参考に分かりやすい質問に直したほうが、回答が得られやすくなると思います。コードは```で囲って整形しましょう。「Webで色々調べたのですが」は具体的にどのようなページを調べて、ご自身のコードとの違いがどのようにあるかなども、分かるレベルで説明したほうが良いです。
fuzzball

2019/07/01 01:13

コードは ``` で囲って下さい。
OBN

2019/07/01 01:27

すみません、何度も更新しているのですが反映されません…。 previewでは反映されているのですが…次質問や回答する機会があれば気を付けます。
fuzzball

2019/07/01 01:35 編集

質問投稿画面の右下にある「更新する」を押しても更新されないということでしょうか?
OBN

2019/07/01 01:41

あ、できました!更新内容が空欄のままだったので編集できていなかったようです。 すみません、プログラミングどころかPC初心者なので…今後気を付けます。
guest

回答1

0

ベストアンサー

ScrollViewのcontentSizeはサイズの計算等が難しくて使いづらいので、
ScrollViewの上にStackViewを乗せてcontentSizeをStackViewに計算してもらうようにしてみました。
(参考: https://qiita.com/Masataka-n/items/c19456f172627359d0d8 )

Storyboardは以下のようにしました。
ScrollViewを画面いっぱいになるようにAutolayoutの制約をつけて、
さらにその上にStackView(Horizontal Stack View)を乗せてScrollViewに対して縦横全てのスペースが0になるように制約をつけます。
横方向にスクロールするようにしたいのでScrollViewに対して同じ高さになるような制約もつけてください。
追加したStackViewのAlignmentはFill、DistributionはEqual Spacing、Spacingは0にします。
これだけではエラーが出るのでStackViewを水平方向の中心に来るようにPriority750で制約を追加します。

Storyboard

ViewControllerは以下のようになります。
StackViewにUIViewを一枚追加してその上にLabelやLottieのViewを乗せるようにします。
普段あまりコードでAutolayoutの制約をつけたりしないので、かなり雑で申し訳ありません。
またLottieは入れてないのでコメントアウトしてあります。

薄く白色になっている部分がLottieのViewになります。

Swift

1class ViewController: UIViewController { 2 3 var onboardStringArray = ["a","i","u","e","o","あ","い","う"] 4 var onboardColors: [UIColor] = [.blue, .red, .yellow, .orange, .green, .purple, .brown, .magenta] 5 6 @IBOutlet var scrollView: UIScrollView! 7 @IBOutlet weak var stackView: UIStackView! 8 9 var animationArray = ["onboard1","onboard2","onboard3","onboard4","onboard5","onboard6","onboard7","onboard8"] 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 setUpScroll() 14 } 15 16 func setUpScroll(){ 17 scrollView.isPagingEnabled = true 18 scrollView.showsHorizontalScrollIndicator = false 19 20 for i in 0...7{ 21 22 // OnboardView 23 // StackView に追加する UIView 高さは StackView の Fill により伸びるので 24 // 幅だけ Autolayout で指定してあげる 25 let onboardView = UIView(frame: .zero) 26 onboardView.backgroundColor = onboardColors[i] 27 28 // Lottie Animation View 29 // OnboardView の上に乗せる Lottie の AnimationView 30 let animationView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.width)) 31 animationView.backgroundColor = .white 32 //animationView.animation = animation 33 //animationView.contentMode = .scaleAspectFit 34 //animationView.loopMode = .loop 35 //animationView.play() 36 onboardView.addSubview(animationView) 37 38 // Label 39 // OnboardView の上に乗せる Label 40 let onboardLabel = UILabel() 41 onboardLabel.translatesAutoresizingMaskIntoConstraints = false 42 onboardLabel.font = UIFont.boldSystemFont(ofSize: 15.0) 43 onboardLabel.textAlignment = .center 44 onboardLabel.text = onboardStringArray[i] 45 onboardView.addSubview(onboardLabel) 46 47 // StackView 48 // OnboardView を StackView の arrangedSubview に追加 49 stackView.addArrangedSubview(onboardView) 50 51 // Autolayout 52 NSLayoutConstraint.activate([ 53 // Onboard 54 onboardView.widthAnchor.constraint(equalTo: self.view.widthAnchor, constant: 0), 55 56 // Lottie Animation View 57 animationView.topAnchor.constraint(equalTo: onboardView.topAnchor, constant: 0), 58 animationView.leadingAnchor.constraint(equalTo: onboardView.leadingAnchor, constant: 0), 59 animationView.trailingAnchor.constraint(equalTo: onboardView.trailingAnchor, constant: 0), 60 animationView.heightAnchor.constraint(equalToConstant: self.view.frame.width), 61 62 // Label 63 onboardLabel.topAnchor.constraint(equalTo: animationView.bottomAnchor, constant: 24.0), 64 onboardLabel.leadingAnchor.constraint(equalTo: onboardView.leadingAnchor, constant: 0), 65 onboardLabel.trailingAnchor.constraint(equalTo: onboardView.trailingAnchor, constant: 0), 66 ]) 67 } 68 } 69} 70 71

2019/07/03 追記

これだけではエラーが出るのでStackViewを水平方向の中心に来るようにPriority750で制約を追加します。

この部分ですがScrollViewには以下のようなエラーが出ていると思います。

Need constraints for: X position or width

エラーの通りX座標方向の制約もしくは幅の制約をつけることで解決することができるので、
以下のようにしてX座標方向(水平方向)の中心に来るように制約を追加します。

まずAlignから水平方向の中心に来るような制約を付けます。

Alignの追加

このままではコードで追加しているAutolayoutの制約とぶつかってしまい、
エラーが出てしまうので、ぶつかった際にブレイクするように以下のようにして優先度を下げます。
追加した制約のEditからPriorityHighにます。

優先度を下げる

2019/07/04 追記

この画面から外面遷移するためのButtonを置きたいです。

こちらについてですが、
ScrollViewと同じ階層にボタンを置いてしまえば表示されると思います。

ボタンの配置

あとはその状態でAutolayoutの制約を追加してしまえば大丈夫です。

ボタンの制約

投稿2019/06/28 02:42

編集2019/07/04 00:37
hayabusabusash

総合スコア767

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

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

OBN

2019/07/01 01:04

回答ありがとうございます!すごく分かりやすくて無事にできました! 普段はStory Boardで作業しているのでコードでadd subViewした時の制約のつけ方がわからなかったのですが、とても参考になりました!
OBN

2019/07/02 12:28 編集

…度々すみません、『これだけではエラーが出るのでStackViewを水平方向の中心に来るようにPriority750で制約を追加します。』ここの部分のやり方がわかりません。下記の問題に関係しているかもです。 StackViewの縦幅はScrollViewとEqual Heightsにすれば良いのはわかったのですが、Widthは制約がないままなのでエラーが出ています。 そのままStackViewにViewを一枚置くとエラーは消えるのですが、Viewのサイズが左半分ぐらいになってしまい、Viewをドラッグして伸ばし、そこにButtonなどのパーツを置くと、Main.storyboard: warning: Auto Layout Localization: Views without any layout constraints may clip their content or overlap other views.のエラーが出てしまい、ビルドしても、Buttonは表示されず、画面遷移が行えません。 丸二日ほど悩みましたが、解決できなかったのでお答え頂けると助かります。
hayabusabusash

2019/07/03 03:24

遅くなってしまい申し訳ありません。回答を編集しました! もし他にもわからない点等ありましたら教えてください。
OBN

2019/07/03 09:21 編集

ご丁寧にありがとうございます!Priorityが理解できていませんでした…。 優先度を下げるとコードでの制約とケンカしなくなるんですね! あと、一つだけよろしいでしょうか?この画面から外面遷移するためのButtonを置きたいです。 ご教授頂いた方法でAutolayoutは思うようになったのですが、StackViewにViewを一枚置いて、そのViewの中にButtonを置くという方法では、Buttonが表示されません…。 Viewを置くところまではエラーはないのですが、Viewの中にButtonを置くと、 Main.storyboard: warning: Auto Layout Localization: Views without any layout constraints may clip their content or overlap other views. とエラーが出てしまいます…。このままBuildするとButtonは表示されません。 何度も申し訳ありませんが、ご教授頂けると助かります。
hayabusabusash

2019/07/04 00:39

追記しました! コードでレイアウトを作るのかStoryboardで作るのかもう少し整理した方が見やすかったかもしれません... 申し訳ありません。
OBN

2019/07/04 00:58

ありがとうございます!StackViewにViewを一枚置いていたので階層がおかしくなっていたみたいです… StoryBoardとコードでのUI生成合わせると混乱しちゃいます。これを機にコードのみでのUI構築も勉強してみようと思います。…SwiftUIもコードの方が恩恵大きそうですし。 大変お世話になりました!聞くばかりでなく答えられるように励みます!…また聞いたときはお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問