我在不同的视图中制作了一些UIScrollView,它们都在没有自动布局的情况下工作。我打开了自动布局,因为它对我的应用程序更好。但从那以后,我的UIScrollView出现了一个大问题:没有人在滚动,它们不起作用。
这是我的UIScrollView:代码
.m:
-(viewDidLoad) {
scrollerHome.contentSize = CGSizeMake(320, 1000);
scrollerHome.scrollEnabled = YES;
[self.view addSubview:scrollerHome];
scrollerHome.showsHorizontalScrollIndicator = false;
scrollerHome.showsVerticalScrollIndicator = false;
[super viewDidLoad];
}
.h:
@interface ViewController : UIViewController{
IBOutlet UIScrollView *scrollerHome;
}
因为我打开了自动布局,所以我必须添加一些代码吗?
做任何事情之前都应该调用[super-viewDidLoad]!
在自动布局中,不手动设置contentSize
。自动布局与滚动视图的工作方式略有不同,因此滚动视图的contentSize
由滚动视图的子视图的约束决定。
如果您试图将contentSize
强制设置为某个较大的大小(例如,您正在实现某个无限滚动器),您可以添加一个适当大小的子视图,例如:
UIView *containerView = [[UIView alloc] init];
containerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:containerView];
NSDictionary *views = NSDictionaryOfVariableBindings(containerView);
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView]|" options:0 metrics:nil views:views]];
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView(1000)]|" options:0 metrics:nil views:views]];
但是,如果您试图在添加子视图之前设置contentSize
,则通常不必执行任何操作,例如上面的代码片段。只需添加子视图,提供它们的约束,自动布局就会自动调整滚动视图的contentSize
。
如上所述,使用自动布局,您只需将子视图添加到滚动视图中(带有它们的约束),就会自动为您计算contentSize
。
不过这里有个诀窍。有时您希望根据屏幕的尺寸来调整子视图的大小。但是通常使用|
符号的技术是行不通的。例如,对于滚动视图中的imageview1
,通常的@"H:|[imageview1]|"
不会将imageview1
设置为屏幕的宽度,而是将滚动视图的contentSize
定义为与imageview1
的宽度相匹配,但它没有说明图像视图的宽度应该是多少!
因此,捕获对滚动视图的superview
的引用非常有用。这样,您就可以使用类似@"H:|[imageview1(==superview)]|"
的东西,它不仅表示"使滚动视图的contentSize
等于imageview1
的宽度",而且还表示"将imageview1
的宽度定义为等于滚动视图superview
的宽度"
因此,例如,要在页面滚动视图中添加三个图像,您可以执行以下操作:
UIImageView *imageview1 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"_DSC0004.jpg"]];
imageview1.contentMode = UIViewContentModeScaleAspectFit;
imageview1.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:imageview1];
UIImageView *imageview2 = ... // configured similar to imageview1
UIImageView *imageview3 = ... // configured similar to imageview1
UIView *superview = self.scrollView.superview;
NSDictionary *views = NSDictionaryOfVariableBindings(imageview1, imageview2, imageview3, superview);
// not only define the image view's relation with their immediate scroll view,
// but also explicitly set the size in relation to the superview, too!
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageview1(==superview)][imageview2(==superview)][imageview3(==superview)]|" options:0 metrics:nil views:views]];
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageview1(==superview)]|" options:0 metrics:nil views:views]];
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageview2(==superview)]|" options:0 metrics:nil views:views]];
[superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageview3(==superview)]|" options:0 metrics:nil views:views]];
self.scrollView.pagingEnabled = YES;
来自Apple iOS 6.0发布说明:
"通常,自动布局会将视图的上、左、下和右边缘视为可见边缘。也就是说,如果将视图固定在其超视图的左边缘,则实际上是将其固定在超视图边界的最小x值。更改超视图的边界原点不会更改视图的位置。
UIScrollView类通过更改其边界的原点来滚动其内容。为了使用"自动布局",滚动视图中的上、左、下和右边缘现在表示其内容视图的边缘。"
你可以在这里找到完整的笔记,并在我引用的部分找到你问题的答案。他们给出了如何在混合自动布局环境中使用UIScrollView的代码示例。