ios 使用自动布局在 UIScrollView 中禁用水平滚动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32521625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:36:10  来源:igfitidea点击:

Disable horizontal scroll in UIScrollView with autolayout

iosiphoneswiftuiscrollviewautolayout

提问by Panich Maxim

I want to create view with only vertical scroll. As it turned out it is epic hard to do in iOs. I have done this steps:

我想创建只有垂直滚动的视图。事实证明,在 iO 中很难做到这一点。我已经完成了以下步骤:

1) Create UIViewController in storyboard;

1)在storyboard中创建UIViewController;

2) Add ScrollView inside View in UIViewController and add 0 constrains to each side.

2) 在 UIViewController 的 View 中添加 ScrollView 并在每一侧添加 0 约束。

3) Add elements in scrollview, as result: enter image description here

3)在scrollview中添加元素,结果: 在此处输入图片说明

After I launch my app all works, but:

在我启动我的应用程序后一切正常,但是:

1) How should I disable horizontal scroll? I add 0 constrain to the right to my scrollView + 0 constrain to the right to my uilabel (as u see on screen for some reasons it is not attached to the right, it has different constrain, but in property I set constrain = 0) and, as I thought, label text supposed to be in my screen bounds, but when I launch app I can scroll to right, i.e. uilable text didn't wrap, my scrollview just resize to fit the text.I tried to set my scrollView in code: scrollView.contentSize = CGSize(UIScreen.mainScreen().bounds.width, height: 800), but didn't help.

1)我应该如何禁用水平滚动?我将 0 约束添加到我的 scrollView 右侧 + 0 约束到我的 uilabel 右侧(正如您在屏幕上看到的,由于某些原因它没有附加到右侧,它具有不同的约束,但在属性中我设置了约束 = 0)而且,正如我所想,标签文本应该在我的屏幕边界内,但是当我启动应用程序时,我可以向右滚动,即 uilable 文本没有换行,我的滚动视图只是调整大小以适应文本。我试图设置我的滚动视图在代码中:scrollView.contentSize = CGSize(UIScreen.mainScreen().bounds.width, height: 800),但没有帮助。

2) If I scroll to much, then blank space appears and this is not cool, how to fix it?

2)如果我滚动到很多,然后出现空白,这不酷,如何解决?

回答by ifau

1) Horizontal scroll enables automatically when the content width in scrollView more than width of scrollView. Therefore, in order to avoid horizontal scrolling is necessary to make width of the content inside scrollView less than or equal to scrollView width.

1) 当scrollView中的内容宽度大于scrollView的宽度时,自动启用水平滚动。因此,为了避免水平滚动,需要让scrollView里面内容的宽度小于等于scrollView的宽度。

Leading spaceand trailing spacecan't set specific width to views, they just stretch them. In regular views, they no stretch for more than width of view, but scrollView is a special view, actually, with an infinite content width. Therefore, trailing spaceand leading spaceconstraints in scrollView change the width of views to their maximum possible values (In case with UILabel you can see resize to fit the text).

Leading space并且trailing space不能为视图设置特定的宽度,他们只是拉伸它们。在常规视图中,它们不会拉伸超过视图的宽度,但 scrollView 是一个特殊的视图,实际上,具有无限的内容宽度。因此,trailing spaceleading space滚动型约束改变意见,其最大可能值宽度(如果用的UILabel你可以看到调整大小以适应文本)。

To avoid horizontal scrolling, you need to set specific width of each view, less than or equal to scrollView width. Specific width of views may be set with width constraints.

为避免水平滚动,您需要设置每个视图的特定宽度,小于或等于 scrollView 宽度。可以使用 设置特定的视图宽度width constraints

Instead of setting each view width, much better to add a view–container and set width to it, and inside it place the views as needed.

与其设置每个视图的宽度,不如添加一个视图容器并为其设置宽度,然后根据需要在其中放置视图。

Views hierarchy:

视图层次结构:

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

Autolayout constraints:

自动布局约束:

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

To set width equal constraintctrl+drag from containerViewto scrollView.

设置width equal constraintctrl+drag from containerViewto scrollView

width equal constraint

宽度相等约束

2) Vertical scroll is dependent on the total height of content. Blank space can be, if the last element inside containerViewhas a large value of the bottom space to superview.

2)垂直滚动取决于内容的总高度。空格可以,如果里面的最后一个元素的containerView值很大bottom space to superview

Or do you mean bounce effect? You can disable vertical bounce of scrollView.

或者你的意思是反弹效果?您可以禁用 scrollView 的垂直反弹。

回答by Johannes Fahrenkrug

You can also easily do this in code. In my case, I have a UIStackViewthat's the only subview of a UIScrollView

您也可以在代码中轻松完成此操作。就我而言,我有一个UIStackViewthat 是a的唯一子视图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

The NSLayoutConstraint.activatebit is taken from Dave DeLong's excellent UIView extension here: https://github.com/davedelong/MVCTodo/blob/master/MVCTodo/Extensions/UIView.swift#L26

NSLayoutConstraint.activate位取自 Dave DeLong 出色的 UIView 扩展:https: //github.com/davedelong/MVCTodo/blob/master/MVCTodo/Extensions/UIView.swift#L26