自动布局 + UIScrollView 和单个子视图
Auto Layout + UIScrollView and single subview
只是玩弄自动布局和 UIScrollView。我在这里错过了什么?这会在屏幕底部显示一个蓝色的 scrollView,但我看不到 contentView。视图调试器也无话可说。有任何想法吗?
//
// ViewController.m
// Fit
//
// Created by Adam Dahan on 2015-03-13.
// Copyright (c) 2015 Adam Dahan. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
{
UIScrollView *scrollView;
UIView *contentView;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self createViews];
[self constrainScrollView];
[self constrainContentView];
}
- (void)createViews
{
#pragma Initialize a scrollView
scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.backgroundColor = [UIColor blueColor];
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
[self.view addSubview:scrollView];
#pragma Initialize a contentView for the scrollView
contentView = [[UIView alloc] initWithFrame:CGRectZero];
contentView.backgroundColor = [UIColor redColor];
contentView.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:contentView];
}
- (void)constrainScrollView
{
#pragma scrollView vertical constraints
NSArray *cns = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[scrollView(40)]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(scrollView)];
[self.view addConstraints:cns];
#pragma scrollView horizontal constraints
cns = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(scrollView)];
[self.view addConstraints:cns];
}
- (void)constrainContentView
{
#pragma contentView vertical constraints
NSArray *cns = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(scrollView, contentView)];
[scrollView addConstraints:cns];
#pragma contentView horizontal constraints
cns = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(scrollView, contentView)];
[scrollView addConstraints:cns];
}
@end
你真的应该看看 Technical Note TN2154 UIScrollView And Autolayout。
你的方式让系统无法决定scrollView的contentSize。
主要思想是无论你选择哪种方式,让scrollView知道contentSize是多少。
使用自动布局时,滚动视图会稍微复杂一些。该框架是根据其他视图的约束定义的(因为您将是您在 constainScrollView
方法中添加的视图)。
但是 contentSize
是根据 scrollView
内部视图的约束定义的。对于您的情况,contentSize 是 (0,0),因为内部视图没有宽度或高度限制。
我想您希望这个内部视图填充滚动视图。那么你的约束应该是这样的:
- (void)constrainContentView
{
[self.view layoutIfNeeded]; // This causes the scrollview width and height to be calculated based on the constraints you sent in the previous method
// You could check by adding a breakpoint here, if the scrollview has the frame you would expect
#pragma contentView vertical constraints
NSArray *cns = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[contentView(height)]-|"
options:0
metrics:@{"height":@(CGRectGetHeight(scrollView.frame))}
views:NSDictionaryOfVariableBindings(scrollView, contentView)];
[scrollView addConstraints:cns];
#pragma contentView horizontal constraints
cns = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[contentView(width)]-|"
options:0
metrics:@{"width":@(CGRectGetWidth(self.view.frame))}
views:NSDictionaryOfVariableBindings(scrollView, contentView)];
[scrollView addConstraints:cns];
}
您为 width
和 height
设置的实际值取决于您的需要。
重要的是 scrollView
中的视图需要设置约束,以便 contentSize
可以无歧义地计算。这意味着如果视图没有固有大小(如 UIButton
或 UILabel
),则需要显式添加 width/height 约束。
由于显式设置宽度和高度,在方向更改时您需要更新约束,以便内部视图具有正确的尺寸。
希望这能解决您的问题。
只是玩弄自动布局和 UIScrollView。我在这里错过了什么?这会在屏幕底部显示一个蓝色的 scrollView,但我看不到 contentView。视图调试器也无话可说。有任何想法吗?
//
// ViewController.m
// Fit
//
// Created by Adam Dahan on 2015-03-13.
// Copyright (c) 2015 Adam Dahan. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
{
UIScrollView *scrollView;
UIView *contentView;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self createViews];
[self constrainScrollView];
[self constrainContentView];
}
- (void)createViews
{
#pragma Initialize a scrollView
scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.backgroundColor = [UIColor blueColor];
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
[self.view addSubview:scrollView];
#pragma Initialize a contentView for the scrollView
contentView = [[UIView alloc] initWithFrame:CGRectZero];
contentView.backgroundColor = [UIColor redColor];
contentView.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:contentView];
}
- (void)constrainScrollView
{
#pragma scrollView vertical constraints
NSArray *cns = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[scrollView(40)]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(scrollView)];
[self.view addConstraints:cns];
#pragma scrollView horizontal constraints
cns = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(scrollView)];
[self.view addConstraints:cns];
}
- (void)constrainContentView
{
#pragma contentView vertical constraints
NSArray *cns = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(scrollView, contentView)];
[scrollView addConstraints:cns];
#pragma contentView horizontal constraints
cns = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(scrollView, contentView)];
[scrollView addConstraints:cns];
}
@end
你真的应该看看 Technical Note TN2154 UIScrollView And Autolayout。
你的方式让系统无法决定scrollView的contentSize。
主要思想是无论你选择哪种方式,让scrollView知道contentSize是多少。
使用自动布局时,滚动视图会稍微复杂一些。该框架是根据其他视图的约束定义的(因为您将是您在 constainScrollView
方法中添加的视图)。
但是 contentSize
是根据 scrollView
内部视图的约束定义的。对于您的情况,contentSize 是 (0,0),因为内部视图没有宽度或高度限制。
我想您希望这个内部视图填充滚动视图。那么你的约束应该是这样的:
- (void)constrainContentView
{
[self.view layoutIfNeeded]; // This causes the scrollview width and height to be calculated based on the constraints you sent in the previous method
// You could check by adding a breakpoint here, if the scrollview has the frame you would expect
#pragma contentView vertical constraints
NSArray *cns = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[contentView(height)]-|"
options:0
metrics:@{"height":@(CGRectGetHeight(scrollView.frame))}
views:NSDictionaryOfVariableBindings(scrollView, contentView)];
[scrollView addConstraints:cns];
#pragma contentView horizontal constraints
cns = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[contentView(width)]-|"
options:0
metrics:@{"width":@(CGRectGetWidth(self.view.frame))}
views:NSDictionaryOfVariableBindings(scrollView, contentView)];
[scrollView addConstraints:cns];
}
您为 width
和 height
设置的实际值取决于您的需要。
重要的是 scrollView
中的视图需要设置约束,以便 contentSize
可以无歧义地计算。这意味着如果视图没有固有大小(如 UIButton
或 UILabel
),则需要显式添加 width/height 约束。
由于显式设置宽度和高度,在方向更改时您需要更新约束,以便内部视图具有正确的尺寸。
希望这能解决您的问题。