UIScrollView AutoLayout Vertical Only

为君一笑 提交于 2019-12-30 03:41:39

问题


I want to get the AutoLayout working with the UIScrollView and am having a little trouble with it. Here is what I did:

  1. Add a UIScrollView inside the Main View with frame: [top: 0, left: 0, width: 320, height: 568]

  2. Add UIView "ContentView" inside the UIScrollView with frame and bgcolor black: [top: 0, left: 0, width: 320, height: 568]

  3. Setup UIScrollView constraints: [top: 0, bottom: 0, left: 0, right: 0]

  4. Setup "ContentView" constraints: [top: 0, bottom: 0, left: 0, right: 0]

  5. Align the items inside the "ContentView"

  6. Set Main View bgcolor to gray (to see what's going on)

Here is a screenshot of the problem:

1

For some reason, the constraints make the content view be in the middle of the screen. Also, it scrolls in every direction. I want the content to be scrollable only in vertical direction like in UITableView. so that I can't move it like below:

What am I doing wrong? I have checked all the tutorials and answers I can find in StackOverflow and Google, and no one actually has just a bizarre problem, so I am asking for help.

EDIT: I also added ContentView's width and height as constraints and that didn't help either.


回答1:


For disabling the horizontal scroll, you can set the content size in the (void)scrollViewDidScroll method.

[self.scrollView setContentOffset: CGPointMake(0, self.scrollView.contentOffset.y)];

You'll also want to set the directional lock so only 1 scroll direction is used at a time. https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScrollView_Class/index.html#//apple_ref/occ/instp/UIScrollView/directionalLockEnabled

self.scrollView.directionalLockEnabled = YES;



回答2:


You can do this entirely using constraints and it's really easy.

The UIScrollView just needs to understand how much width and space it has inside it. So it needs to have something pinned to the Leading, Trailing, Top & Bottom constraints. Also the width and height of the content needs to be fixed (this does not mean I have to specificy it. I can still use constraints to achieve this.)

  1. Add a UIScrollView and position as required.
  2. Add a UIView inside the UIScrollView for the content.
  3. Set the Leading, Trailing, Top & Bottom constraints of the content UIView to be 0.
  4. Add an Equal Width constraint to the UIScrollView and UIView. This will make it vertically scrolling only.
  5. You now need to set the height of the content UIView. You can then either specify the height of the content view (blech) or use the height of the controls contained within by making sure the bottom control is constrained to the bottom of the content view.

I did this and it worked a treat.




回答3:


To summarize the Leszek S' answer:

In order to have a vertically scrolling view, all the views inside the scroll view must have their width constraint set. Easy to just set to the scroll view's superview.

The reason is that the scroll view will not scroll horizontally so as long as none of its subviews need to scroll horizontally. For example, if you have a label, set to 0 lines, auto layout will try to make the label as wide as it can before it starts adding lines and line breaks. If there are no explicit width constraints on the label it'll just make the scroll view content area wider. Constraints for trailing to the scroll view are ignored.

If you have a bunch of views, you might want to put them inside a single containing view like in that video. For my case, I only have 5 or 6 labels which can dynamically change height, but should never change width so I just made them all the same width as the scroll view. And bingo, vertically scrolling view with labels that grow or shrink depending on the text.




回答4:


I have written a function that allows to scroll content vertically but not horizontally. It creates a UIView with limited width inside scrollview and embeds all scrollview subviews in it.

TegScrolledContent.createContentView(scrollView)

https://github.com/exchangegroup/scrollable-content-ios




回答5:


Along with @derek's answer I would like to add that setting contentOffset always in scrollViewDidScroll will cause performance issue . So please check only if x is not 0 then set contentOffset

    if(contentOffset.x != 0){
        setContentOffset(CGPointMake(0, contentOffset.y), animated: false)
    }

and yes to the scrollview

directionalLockEnabled = true



回答6:


Give content view explicit height and width constraints




回答7:


Below is a snippet that I have used to achieve a vertical-only scroll view. It works by adding a content view as a child view of a scroll view, then constraining the width of that content view to the width of the parent scroll view. From then, all of the subviews should be added to the content view rather than to the scroll view.

// View that will contain content of scroll view. Width is constrained to the width of the scroll view.
UIView *contentView = [[UIView alloc] init];
contentView.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:contentView];

views[@"contentView"] = contentView;
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:nil views:views]];

// Now, add all your subviews to contentView


来源:https://stackoverflow.com/questions/25981635/uiscrollview-autolayout-vertical-only

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!