web-dev-qa-db-ja.com

自動レイアウトでUIScrollViewの水平スクロールを無効にします

垂直スクロールのみでビューを作成したい。結局のところ、IOで行うのは非常に困難です。私はこの手順を実行しました:

1)ストーリーボードでUIViewControllerを作成します。

2)UIViewControllerのView内にScrollViewを追加し、両側に0の制約を追加します。

3)scrollviewに要素を追加し、結果として: enter image description here

アプリを起動した後はすべて動作しますが、

1)水平スクロールを無効にするにはどうすればよいですか? scrollViewの右側に0の制約を追加し、uilabelの右側に0の制約を追加します(何らかの理由で画面に表示されるように、右側に接続されていません。異なる制約がありますが、プロパティではconstrain = 0に設定します)そして、私が思ったように、ラベルテキストは画面の境界内にあるはずですが、アプリを起動すると右にスクロールできます。つまり、利用可能なテキストが折り返されず、スクロールビューはテキストに合わせてサイズが変更されます。コード:scrollView.contentSize = CGSize(UIScreen.mainScreen().bounds.width, height: 800)が、助けにはなりませんでした。

2)スクロールすると、空白が表示されますが、これはクールではありません。どうすれば修正できますか?

21
Panich Maxim

1)scrollViewのコンテンツの幅がscrollViewの幅を超えると、水平スクロールが自動的に有効になります。したがって、scrollView内のコンテンツの幅をscrollViewの幅以下にするために、水平スクロールを回避する必要があります。

Leading spaceおよびtrailing spaceはビューに特定の幅を設定できず、単にそれらを拡大します。通常のビューでは、ビューの幅を超えて伸縮することはありませんが、scrollViewは実際にはコンテンツの幅が無限である特別なビューです。したがって、scrollViewのtrailing spaceおよびleading space制約は、ビューの幅を可能な最大値に変更します(UILabelの場合、テキストに合わせてサイズ変更を確認できます)。

水平スクロールを回避するには、各ビューの特定の幅をscrollView幅以下に設定する必要があります。ビューの特定の幅は、width constraintsで設定できます。

各ビューの幅を設定する代わりに、ビューコンテナを追加して幅を設定し、その中に必要に応じてビューを配置する方がはるかに適切です。

ビュー階層:

View
    -> ScrollView
        -> ContainerView
            -> UILabel
            -> UILabel
            -> ... other views that you need

自動レイアウトの制約:

ScrollView
    -> leading space to View : 0
    -> trailing space to View : 0
    -> top space to View : 0
    -> bottom space to View : 0

Container View
    -> leading space to ScrollView : 0
    -> trailing space to ScrollView : 0
    -> top space to ScrollView : 0
    -> bottom space to ScrollView : 0
    -> width equal to ScrollView : 0

width equal constraint ctrl +ドラッグをcontainerViewからscrollViewに設定するには。

width equal constraint

2)垂直スクロールは、コンテンツの全高に依存します。 containerView内の最後の要素がbottom space to superviewの大きな値を持っている場合、空白ができます。

または、バウンス効果を意味しますか? scrollViewの垂直バウンスを無効にできます。

59
ifau

コードでこれを簡単に行うこともできます。私の場合、UIStackViewの唯一のサブビューであるUIScrollViewがあります

// Create the stack view
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
// Add things to the stack view....

// Add it as a subview to the scroll view
scrollView.addSubview(stackView)

// Use auto layout to pin the stack view's sides to the scroll view
NSLayoutConstraint.activate([
    stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
    scrollView.trailingAnchor.constraint(equalTo: stackView.trailingAnchor),

    stackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
    scrollView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor)
])

// Now make sure the thing doesn't scroll horizontally
let margin: CGFloat = 40

scrollView.contentInset = UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin)

scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true

let stackViewWidthConstraint = stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
stackViewWidthConstraint.constant = -(margin * 2)
stackViewWidthConstraint.isActive = true

NSLayoutConstraint.activateビットは、Dave DeLongの優れたUIView拡張機能から取得されます。 https://github.com/davedelong/MVCTodo/blob/master/MVCTodo/Extensions/UIView.Swift#L26

0