web-dev-qa-db-ja.com

自動レイアウトでのスクロールビューの使用Swift

私はこの質問が何度も尋ねられていることを知っていますが、これは私が長い間苦労してきた問題であり、現在の答えやチュートリアルがあっても他の人もそうであると確信しています。

スクロールビューを追加するときは、次の手順を実行します。

  1. Scroll ViewをView Controllerの元のビューのサブビューとして追加します。上下左右にピン留めします。 「マージンに制約」がオフになっていることを確認します。

  2. UIViewをスクロールビューのサブビューとして追加します。ピンの上下左右の制約。

  3. コンテンツビューとView Controllerビューの間に等幅の制約を追加します。

この時点でアプリを実行すると、コンテンツビューは表示されず、スクロールビューが画面全体に表示されます。

  1. 次に、すべてをテストするために、4つのUIViewを含む要素をコンテンツビューに追加します。各UIViewに、上、左、および右の制約を与えます。そして最後のUIViewは最下位の制約です。

この時点では、アプリを実行すると、コンテンツビューとスクロールビューはそれぞれ画面の約半分を占め、コンテンツビューをスクロールできます。下の写真をご覧ください。

私は見つけることができるすべてのチュートリアルに従って、すべてのSO答えを実装しようとしましたが、私はそれを機能させることができません。誰かがこれに遭遇したか、あなたの助けを知っている場合とても感謝しています!

緑はコンテンツビューで、青はスクロールビューです

enter image description here

スクロールビューとサブビューの制約

enter image description here

15
01Riv

私は他の答えの助けを借りてこれを理解しましたが、私が望むように機能させるためにいくつかの調整をしなければなりませんでした。私が行ったステップは次のとおりです。

  1. メインビューのサブビューとしてスクロールビューを追加します。

  2. スクロールビューを選択し、[マージンに制約]チェックボックスをオフにし、上、左、右、下、制約を固定します

  3. UIViewをスクロールビューのサブビューとして追加します。このビューに「コンテンツビュー」という名前を付けます

  4. コンテンツビューを選択し、上下左右の制約を固定します。次に、中央に水平方向の制約を追加します。

  5. 次に、コンテンツビューからメインビューに等しい幅と等しい高さの制約を追加します。

  6. コンテンツビュー内に必要な要素を追加します。追加した要素の上部、左、右、および高さの制約を固定します。

  7. コンテンツビュー内の一番下のアイテムで、一番下の制約を固定します。この制約を選択し、「より大きい」または「等しい」に変更します。定数を20に変更します。

コンテンツビュー内のアイテムに追加された制約、特に最後のアイテムに追加された下部の制約は非常に重要です。スクロールビューのコンテンツサイズを決定するのに役立ちます。説明したように下部の制約を追加すると、コンテンツが大きすぎて画面に収まらない場合はビューをスクロールでき、コンテンツが画面に収まらない場合はスクロールを無効にします。

58
01Riv

私はコードで簡単なビューを作成しましたが、これは自明であり、役立つかもしれません。スクロールビューを機能させるために必要なすべての手順の概要を示します。

不明な点がある場合は、お気軽にコメントをお送りください。

import UIKit

class TutorialView: UIView {

    lazy var sv: UIScrollView = {
        let object = UIScrollView()

        object.backgroundColor = UIColor.whiteColor()
        object.translatesAutoresizingMaskIntoConstraints = false
        return object
    }()

    lazy var tutorialPageOne: UIView = {
        let object = UIView(frame: UIScreen.mainScreen().bounds)
        object.translatesAutoresizingMaskIntoConstraints = false
        object.backgroundColor = UIColor.cyanColor()

        return object
    }()

    lazy var tutorialPageTwo: UIView = {
        let object = UIView(frame: UIScreen.mainScreen().bounds)
        object.translatesAutoresizingMaskIntoConstraints = false
        object.backgroundColor = UIColor.lightGrayColor()

        return object
    }()

    lazy var tutorialPageThree: UIView = {
        let object = UIView(frame: UIScreen.mainScreen().bounds)
        object.translatesAutoresizingMaskIntoConstraints = false
        object.backgroundColor = UIColor.redColor()

        return object
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.addSubview(self.sv)
        self.sv.addSubview(self.tutorialPageOne)
        self.sv.addSubview(self.tutorialPageTwo)
        self.sv.addSubview(self.tutorialPageThree)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let vc = nextResponder() as? UIViewController
        let mainSreenWidth = UIScreen.mainScreen().bounds.size.width
        let mainScreenHeight = UIScreen.mainScreen().bounds.size.height

        NSLayoutConstraint.activateConstraints([
            self.sv.topAnchor.constraintEqualToAnchor(vc?.topLayoutGuide.bottomAnchor),
            self.sv.leadingAnchor.constraintEqualToAnchor(self.leadingAnchor),
            self.sv.bottomAnchor.constraintEqualToAnchor(vc?.bottomLayoutGuide.topAnchor),
            self.sv.trailingAnchor.constraintEqualToAnchor(self.trailingAnchor)
        ])

        NSLayoutConstraint.activateConstraints([
            self.tutorialPageOne.widthAnchor.constraintEqualToConstant(mainSreenWidth),
            self.tutorialPageOne.heightAnchor.constraintEqualToConstant(mainScreenHeight),
            self.tutorialPageOne.topAnchor.constraintEqualToAnchor(self.sv.topAnchor),
            self.tutorialPageOne.leadingAnchor.constraintEqualToAnchor(self.sv.leadingAnchor),
            self.tutorialPageOne.bottomAnchor.constraintEqualToAnchor(self.sv.bottomAnchor)
        ])


        NSLayoutConstraint.activateConstraints([
            self.tutorialPageTwo.widthAnchor.constraintEqualToConstant(mainSreenWidth),
            self.tutorialPageTwo.heightAnchor.constraintEqualToConstant(mainScreenHeight),
            self.tutorialPageTwo.topAnchor.constraintEqualToAnchor(self.sv.topAnchor),
            self.tutorialPageTwo.leadingAnchor.constraintEqualToAnchor(self.tutorialPageOne.trailingAnchor),
            self.tutorialPageTwo.bottomAnchor.constraintEqualToAnchor(self.sv.bottomAnchor)
        ])

        NSLayoutConstraint.activateConstraints([
            self.tutorialPageThree.widthAnchor.constraintEqualToConstant(mainSreenWidth),
            self.tutorialPageThree.heightAnchor.constraintEqualToConstant(mainScreenHeight),
            self.tutorialPageThree.topAnchor.constraintEqualToAnchor(self.sv.topAnchor),
            self.tutorialPageThree.leadingAnchor.constraintEqualToAnchor(self.tutorialPageTwo.trailingAnchor),
            self.tutorialPageThree.bottomAnchor.constraintEqualToAnchor(self.sv.bottomAnchor),
            self.tutorialPageThree.trailingAnchor.constraintEqualToAnchor(self.sv.trailingAnchor)
        ])

    }
}
4

この手順に従ってください:

  1. メインビューのサブビューとしてスクロールビューを追加します。
  2. スクロールビューを選択し、「マージンへの制約」のチェックを外しますで、上、左、右、下、制約を固定します
  3. UIViewをスクロールビューのサブビューとして追加します。このビューに「コンテンツビュー」という名前を付けます
  4. 「コンテンツビュー」制約(上部、下部、先頭および末尾)を(0,0,0,0)に設定します。
  5. これで、このビューのような階層を見ることができます->スクロールビュー->ビュー(コンテンツビュー)
  6. 「コンテンツビュー」には、親ビューと等しい幅と等しい高さが必要です。
  7. コンテンツビューの-高さの制約を選択し、優先度 withwith -low(250)を設定します。
  8. これで、任意の高さでビューを設計できます。
  9. コンテンツビュー内に必要な要素を追加します。 ピン上部、左、右、および高さ追加されたばかりの要素に対する制約。
  10. おめでとうございます。自動レイアウト付きのスクロールビューが完成しました。
3

UIScrollViewとAutoLayoutの例を探している人に。 SnapKitを使用しています。Xcode9で動作していますSwift 3

    let scrollView = UIScrollView()
    view.addSubview(scrollView)
    scrollView.snp.makeConstraints { (make) in
        make.edges.equalTo(view).inset(UIEdgeInsetsMake(0, 0, 0, 0))
        make.top.left.right.equalTo(view)
    }

    let view1 = UIView()
    view1.backgroundColor = UIColor.red
    scrollView.addSubview(view1)
    view1.snp.makeConstraints { (make) in
        make.top.equalTo(scrollView.snp.top).offset(0)
        make.left.equalTo(scrollView.snp.left).offset(0)
        make.width.equalTo(scrollView.snp.width)
        make.height.equalTo(300)
    }

    let view2 = UIView()
    view2.backgroundColor = UIColor.blue
    scrollView.addSubview(view2)
    view2.snp.makeConstraints { (make) in
        make.top.equalTo(view1.snp.bottom)
        make.left.equalTo(scrollView)
        make.width.equalTo(scrollView)
        make.height.equalTo(300)
    }

    let view3 = UIView()
    view3.backgroundColor = UIColor.green
    scrollView.addSubview(view3)
    view3.snp.makeConstraints { (make) in
        make.top.equalTo(view2.snp.bottom)
        make.left.equalTo(scrollView)
        make.width.equalTo(scrollView)
        make.height.equalTo(100)
        make.bottom.equalTo(scrollView.snp.bottom).offset(-20)
    }
2
nmh

私はこれを理解するためにかなりの時間を費やしましたが、それは非常に単純です。これが解決策です。次の手順を実行します

  • ScrollViewをメインビューのサブビューとして追加します
  • 上、左、右、下、コンテナ内で水平方向、コンテナ内で垂直方向にピン留めします。
  • コンテナビューをスクロールビューのサブビューとして追加します
  • 上、左、右、下、コンテナ内で水平方向、コンテナ内で垂直方向にピン留めします。
  • 目的の制約を使用して、コンテナビューにサブビューを追加します。
  • スクロールビューのコンテンツサイズを適宜設定します。

スクロールしてください:)

2
Fahad Azeem

視覚的に表示したいだけです。 ViewControllerのサイズよりも大きいビューを作成する場合は、ViewControllerフォームサイズインスペクターの高さを増やすことができます。シミュレートされたサイズをフリーフォームに選択し、画像に示すように必要な高さを設定すると、viewControllerに上記の高さがあります。

enter image description here

  1. ScrollviewをViewControllerにドラッグし、4つの制約(Leading、Trailing、TopおよびBottom)を適用します enter image description here

  2. ScrollViewと同じ幅と高さを持つ1つのビューをScrollView内にドラッグし、6つの制約(Leading、Trailing、Top、Bottom、FixHeight、= WidthToScrollView)を設定します。私の場合、それに応じて15個のLおよびTスペースと他のマージンがあります。表示するマージンは異なりますが、制約は同じである必要があります。

enter image description hereenter image description here

  1. ビューをそれに応じてドラッグし、制約を設定できます。ビュー内に2つのビューがあります。

enter image description here

  1. 最初のビューでは、Leading、Top、Trailingを設定し、高さを固定したいです。 2番目の場合、Leading、bottom、trailingを設定し、高さを固定したいです。

enter image description hereenter image description here

  1. おめでとうございます!これですべての設定が完了し、アプリが実行されました。

enter image description hereenter image description here

1
Gurjinder Singh

コードなしでscrollView内にUIを作成する方法を知っている最良の方法は次のとおりです。

  1. ScrollViewをuiviewcontrollerに追加し、uiviewcontrollerとその親ビューの間に適切な制約を設定します。
  2. 「ブレースビュー」をスクロールビューに追加します。
  3. 「ブレースビュー」は、最終的なUIの一部ではないため、非表示にする必要があります。
  4. 左、上、右に「ブレースビュー」とUIScrollViewの間に含まれるようにします。高さを制限します。 (高さの制約は任意の数値にすることができます)。中央のxをUIScrollViewの制約に合わせます。

  5. 「ブレースビュー」の下に最終的なUIを追加します。

  6. 最初の最後のUIビューと「ブレースビュー」の間に上部の制約を追加します。
  7. すべての最終的なUIビューを上部または下部の制約とリンクします。
  8. 適切な最終UI制約を追加します。
  9. 最後の最後のUIビューとスクロールビューの間に下部の制約を追加します。 (このconstraint.constantは、最終的なUIの一部であるため重要です)。

以下に簡単な githubプロジェクト の例を示します。

enter image description hereenter image description here

0
Randel G. Smith

UIScrollViewクラスは、境界のOriginを変更してコンテンツをスクロールします。これを自動レイアウトで動作させるには、スクロールビュー内の上端、左端、下端、および右端がコンテンツビューの端を意味するようになりました。

スクロールビューのサブビューの制約により、サイズがいっぱいになる必要があります。このサイズは、スクロールビューのコンテンツサイズとして解釈されます。 (これは、自動レイアウトで使用されるintrinsicContentSizeメソッドと混同しないでください。)スクロールビューのフレームを自動レイアウトでサイズ変更するには、スクロールビューの幅と高さに関する制約を明示するか、スクロールビューの端をサブツリー外のビューに関連付けられています。

Technoteもご覧くださいAppleこの問題について書いた: https://developer.Apple.com/library/ios/technotes/tn2154/_index.html

0
Joride

@ m1234に従って、ただし、同じ高さを解放する必要があります。そうしないと、スクロールが機能しません。私のメソッドは次のようになります。

  1. メインビューのサブビューとしてスクロールビューを追加します。

  2. スクロールビューを選択し、[マージンに制約]チェックボックスをオフにし、上、左、右、下、制約を固定します

  3. UIViewをスクロールビューのサブビューとして追加します。このビューに「コンテンツビュー」という名前を付けます

  4. コンテンツビューを選択し、上下左右の制約を固定します。次に、中央に水平方向の制約を追加します。

  5. 次に、コンテンツビューからメインビューに等しい幅の制約を追加します。

  6. コンテンツビュー内に必要な要素を追加します。追加した要素の上部、左、右、および高さの制約を固定します。

  7. コンテンツビュー内の一番下の項目で、下部の制約を固定します。この制約を選択し、「より大きい」または「等しい」に変更します。定数を20に変更します。

0
Bowcaps