UIScrollView 不适用于自动布局 (iOS 6)



我在不同的视图中制作了一些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的代码示例。

最新更新