如何以编程方式在UIScrollView中用AutoLayout设置子视图?

我用UiScrollview和UIPagectontrol使用Autolayout Progrmatically创build应用程序

我创build了TKScroller作为UIView的子类,我初始化它使用某些模式和数组。

TKScroller.m

-(void)setData{ [self layoutIfNeeded]; CGRect mainFrame=self.frame; [self layoutIfNeeded]; CGRect mainFrame=self.frame; UIView *lastview; NSMutableArray* manualConstraints = [NSMutableArray array]; for (int i=0; i<arrayData.count ; i++) { CGRect frame; frame.origin.x = scrollView.frame.size.width * i; frame.origin.y = 0; frame.size = scrollView.frame.size; UIView *subview = [UIView new]; subview.backgroundColor = [self getRandomColor]; [scrollView addSubview:subview]; if (i==0) { NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:5]; [manualConstraints addObject:b1_top]; NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeLeading multiplier:1 constant:5]; [manualConstraints addObject:b1_left]; NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1 constant:-5]; [manualConstraints addObject:b1_right]; NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:-10]; [manualConstraints addObject:b1_bottom]; [subview layoutIfNeeded]; [scrollView addConstraints:manualConstraints]; lastview=subview; } else{ NSLayoutConstraint* b1_top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:5]; [manualConstraints addObject:b1_top]; NSLayoutConstraint* b1_left = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:lastview attribute:NSLayoutAttributeLeading multiplier:1 constant:5]; [manualConstraints addObject:b1_left]; NSLayoutConstraint* b1_right = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTrailing multiplier:1 constant:-5]; [manualConstraints addObject:b1_right]; NSLayoutConstraint* b1_bottom = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:-10]; [manualConstraints addObject:b1_bottom]; [subview layoutIfNeeded]; [scrollView addConstraints:manualConstraints]; lastview=subview; } } scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayData.count, mainFrame.size.height/2); self.pageControl.currentPage = 0; self.pageControl.numberOfPages = arrayData.count; pageControlBeingUsed = NO; } -(UIColor *)getRandomColor{ int r = arc4random() % 255; int g = arc4random() % 255; int b = arc4random() % 255; return [UIColor colorWithRed:(r/255.0) green:(g/255.0) blue:(b/255.0) alpha:1.0]; } 

现在我正在得到任何子视图,

但如果我改变方向它会给不正确的结果,那么我怎么能给NSLayoutConstraint的子视图滚动视图的限制?

编辑

没有显示添加NSLayoutConstraint子视图后。 我只是缺less一些约束,请纠正我dynamic设置约束。

我的源代码在这里 ,请帮助我。 谢谢。 对不起,语法错误。

这里是一个SO答案已经解释了如何做到这一点与自动布局,他有完美的解释,在这里有垂直textfields有但在你的情况下,你必须设置水平视图的约束。

替代

而是设置约束,你可以设置子视图的框架,并设置在滚动视图,并根据方向,你可以改变滚动视图的子视图的框架。

你的setData方法,

 -(void)setData{ [self layoutIfNeeded]; CGRect mainFrame=scrollView.frame; CGRect frame; for (int i=0; i<arrayData.count ; i++) { CGRect frame; frame.origin.x = scrollView.frame.size.width * i; frame.origin.y = 0; frame.size = scrollView.frame.size; frame.origin=CGPointMake(0, 0); UIView *subview = [[UIView alloc]initWithFrame:frame]; subview.backgroundColor = [self getRandomColor]; [scrollView addSubview:subview]; } scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayData.count, mainFrame.size.height/2); } 

现在你使用NSNotificationCenter可以在设备方向变化的时候得到通知,所以在这个select器方法中调用你的setData方法,

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setData) name:UIDeviceOrientationDidChangeNotification object:nil]; 

现在你setData方法,你需要删除所有的子视图,因为当设备改变方向它会添加新的视图到你的滚动视图,所以删除所有子视图滚动视图设置其框架之前,

  [scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 

确保你从你的class级中删除观察员,

 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } 

在我的经验与AutoLayout (我也使用编程)。 你不应该直接添加视图到你的UIScrollView

你应该做一个UIView 和只有一个 ,你添加作为你的UIScrollView子视图。

一旦完成,您可以将所有子视图添加到此UIView

一切都在这里详细解释: 苹果iOS技术说明TN2154

我知道问题已经解决了。 我希望这个解决scheme可以帮我解决一些人的问题。

下面的代码是将scrollview添加到uiviewcontroller

  self.scrollView = UIScrollView() self.scrollView.backgroundColor = UIColor.greenColor() self.scrollView.setTranslatesAutoresizingMaskIntoConstraints(false) self.scrollView.scrollEnabled=true self.scrollView.pagingEnabled = true self.view.addSubview(self.scrollView) self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView":self.scrollView])) self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["scrollView":self.scrollView])) 

添加滚动视图并添加像这样的子视图/图像(这是一个图像显示全尺寸的滚动视图的例子,如照片应用程序)

 var prev:UIImgeView? for var index = 0; index < self.images.count; ++index { var iview = UIImgeView() iview.setTranslatesAutoresizingMaskIntoConstraints(false) self.scrollView.addSubview(iview) var image = self.images.objectAtIndex(index) as UIImage iview.image = image if (index == 0){ self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[iview(==scrollView)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"scrollView":self.scrollView])) prev = iview } else{ self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prev][iview(==prev)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"prev":prev!])) prev = iview } self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[iview(==scrollView)]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["iview":iview,"scrollView":self.scrollView])) if (index == self.images.count-1){ self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[prev]|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["prev":prev!])) } } 

如果你想让你的TKScroller固定在中心位置并支持方向的改变,你可以简单地把下面的代码放到你的init中

 self.autoresizingMask = UIViewAutoresizingFlexibleWidth; 

你可能需要检查你的所有子视图的TKScroller。 如果你不喜欢自动大小,你可以设置(三个之一)

 self.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;