问题
I want to get the AutoLayout working with the UIScrollView
and am having a little trouble with it. Here is what I did:
Add a
UIScrollView
inside the Main View with frame: [top: 0, left: 0, width: 320, height: 568]Add
UIView
"ContentView" inside theUIScrollView
with frame and bgcolor black: [top: 0, left: 0, width: 320, height: 568]Setup
UIScrollView
constraints: [top: 0, bottom: 0, left: 0, right: 0]Setup "ContentView" constraints: [top: 0, bottom: 0, left: 0, right: 0]
Align the items inside the "ContentView"
Set Main View bgcolor to gray (to see what's going on)
Here is a screenshot of the problem:
1For 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.)
- Add a
UIScrollView
and position as required. - Add a
UIView
inside theUIScrollView
for the content. - Set the
Leading
,Trailing
,Top
&Bottom
constraints of the contentUIView
to be 0. - Add an
Equal Width
constraint to theUIScrollView
andUIView
. This will make it vertically scrolling only. - 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