问题
I am trying to work an example code thats using the 'mixed approach' mention on apple dev link:
I am trying to stack 3 views vertically in UIScrollView. In below example the UIScrollView shows the red view on load but does not scroll as expected. I can scroll a little bit to see the green view below the red view - but the scroll view springs back up and does not scroll to the green view or view below it(blue view). I understand I need a constraint I tried to add one between view 1 & 2 so that view2.top = view1.bottom ,but seems I am missing something.
Also I noticed the content size of the scrollview is zero ( in viewDidAppear method).
Any tips on what I am missing or help on how to get this mixed approach working would be of great!!
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIScrollView* scrollView = ((UIScrollView*)self.view);
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
CGFloat w = self.view.frame.size.width;
CGFloat h = self.view.frame.size.height;
contentView = [[UIView alloc] initWithFrame:CGRectMake(0,0, w, h*3)];
[scrollView addSubview:contentView];
v1 =[[UIView alloc] initWithFrame:CGRectMake(0,0, w, h)];
v2 =[[UIView alloc] initWithFrame:CGRectMake(0,h, w, h)];
v3 =[[UIView alloc] initWithFrame:CGRectMake(0,h*2, w, h)];
v1.backgroundColor = [UIColor redColor];
v2.backgroundColor = [UIColor greenColor];
v3.backgroundColor = [UIColor blueColor];
[contentView addSubview:v1];
[contentView addSubview:v2];
[contentView addSubview:v3];
NSLayoutConstraint *myConstraint =[NSLayoutConstraint
constraintWithItem:v1
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:v2
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0];
[contentView addConstraint:myConstraint];
scrollView.contentSize = contentView.bounds.size;
}
回答1:
I dont understand why you would need a constraint if you are just trying to stack views in a scroll view. I tried your code and it does not scroll well like you said, but I think it is being caused because you are using a UIScrollView as the main view for the view controller, is there a specific reason you want to do it like this?
I changed the code to instead add a UIScrollView to the normal UIView and it works perfectly as expected without using any complicated constraints. Just remember to define the scroll view at the top by using UIScrollView *scrollView;
- (void)viewDidLoad {
[super viewDidLoad];
scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:scrollView];
CGFloat w = self.view.frame.size.width;
CGFloat h = self.view.frame.size.height;
contentView = [[UIView alloc] initWithFrame:CGRectMake(0,0, w, h*3)];
[scrollView addSubview:contentView];
v1 =[[UIView alloc] initWithFrame:CGRectMake(0,0, w, h)];
v2 =[[UIView alloc] initWithFrame:CGRectMake(0,h, w, h)];
v3 =[[UIView alloc] initWithFrame:CGRectMake(0,h*2, w, h)];
v1.backgroundColor = [UIColor redColor];
v2.backgroundColor = [UIColor greenColor];
v3.backgroundColor = [UIColor blueColor];
[contentView addSubview:v1];
[contentView addSubview:v2];
[contentView addSubview:v3];
scrollView.contentSize = contentView.bounds.size;
}
回答2:
I had to struggle alot with stupid pure based auto-layout approach for UIScrollView. I wanted a scrollview that is based on subviews that are auto-layout constraint based and works with rotation. In the end the following "Mixed Approach" code worked for me for a vertical scrolling and kept things simple:
- (void)viewDidLoad {
UIView *contentView;
contentView = [[UIView alloc] initWithFrame:self.scrollView.bounds];
//don't add UIViewAutoresizingFlexibleHeight as that messes things up but next line helps with rotation
contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[scrollView addSubview:contentView];
// DON'T change contentView's translatesAutoresizingMaskIntoConstraints,
// which defaults to YES;
// Set the content size of the scroll view to match the size of the content view
[scrollView setContentSize:CGSizeMake(contentWidth, contentHeight)];
/* the rest of your code here... pre auto-layout style and you can change the origins of subviews to position them within contentView */
[contentView addSubview:subView1];
[contentView addSubview:subView2];
}
The key point to realize is that DO NOT change size of contentView any point later after initialization and adding it to scrollview as that would cause its internal constraints to break but you can still continue to add subviews without worrying about its size.
You'll calculate the scroll view content size independently from size of contentView unless you use the systemLayoutSizeFittingSize: method which I haven't tested still
来源:https://stackoverflow.com/questions/19993595/uiscrollview-with-autolayout-mixed-approach