2016-05-30 58 views
0
let N = 4 
let holder = UIView(frame: CGRectMake(0, 0, someWidth, N * 100)) 
for var i = 0; i <= N; i++ { 
    let content = UIView(frame: CGRect.zero) //height should be 100 
    content.backgroundColor = randomColor() 
    content.translatesAutoresizingMaskIntoConstraints = true 
    holder.addSubview(content) 
} 

上面的代码将添加N UIViews到holder。我想以编程方式使用NSLayoutConstraints垂直显示内容,一个在另一个之上。如何自动布局垂直列表的UIViews,一个在另一个之上?

每个内容应具有100高度每个内容应该对所有4个边缘约束。第一个内容应该有顶部/前导/尾随约束(常量= 0)到holder。最后的内容应该有底部/前导/尾随约束(常量= 0)至holder

内容的其余部分应该具有顶部/底部约束(常数= 8)向另一同级内容。

如何创建这些约束?

+0

你有什么理由宁愿手动布局'NSStackView'? –

回答

1

Vertical page

Samething我为水平页来完成。因此,这里是代码

var scrollView = UIScrollView() 
var contectView = UIView(); 

添加holderview的子视图

self.scrollView.translatesAutoresizingMaskIntoConstraints = false; 
    self.view.addSubview(self.scrollView); 

    self.contectView.translatesAutoresizingMaskIntoConstraints = false; 
    self.scrollView.addSubview(self.contectView); 

为holderView

创建约束
let views = ["contectView" : self.contectView , "scrollview" : self.scrollView ]; 

    // create constraint for scrollview 
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollview]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) 
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollview]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) 

    // create constraint for contectview with low priority for width and height 
    self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[contectView([email protected])]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) 
    self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[contectView([email protected])]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) 

制作水平串约束

 var verticalConstraintsFormat = ""; // create horizantal constraint string 
    let subViews = NSMutableDictionary(); 
    subViews["scrollView"] = self.scrollView; 

创建动态页面

let totalPage : NSInteger = 10; 

    for i in 0...totalPage { 

     // Create your page here 
     let objProductView = UIView() 
     objProductView.translatesAutoresizingMaskIntoConstraints = false; 
     objProductView.backgroundColor = UIColor(white: CGFloat(arc4random()%100)/CGFloat(100), alpha: 1) 
     self.contectView.addSubview(objProductView); 

     let key = NSString(format: "productView%d", i) as NSString 
     subViews[key] = objProductView; 


     if(i==0){ 
      verticalConstraintsFormat = verticalConstraintsFormat.stringByAppendingFormat("V:|-0-[%@(==100)]", key); 
     } 
     else if (i==totalPage) { 
      verticalConstraintsFormat = verticalConstraintsFormat.stringByAppendingFormat("-0-[%@(==100)]-0-|", key); 

     } 
     else{ 
      verticalConstraintsFormat = verticalConstraintsFormat.stringByAppendingFormat("-0-[%@(==100)]", key); 

     } 

     let verticalConstraintsFormat1 = NSString(format:"H:|[%@(==scrollView)]", key); 
     self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(verticalConstraintsFormat1 as String, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: subViews as AnyObject as! [String : AnyObject])); 


    } 
    self.scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(verticalConstraintsFormat as String, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: subViews as AnyObject as! [String : AnyObject])); 

希望这会有所帮助。

1

你可以做这样的事情,

let content = UIView() 
    content.backgroundColor = UIColor.redColor() 
    content.translatesAutoresizingMaskIntoConstraints = false 
    view.addSubview(content) 


    let topConstraint = NSLayoutConstraint(item: content, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0) 
    view.addConstraint(topConstraint) 

    let leadingConstraint = NSLayoutConstraint(item: content, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Leading, multiplier: 1, constant: 0) 
    view.addConstraint(leadingConstraint) 

    let bottomConstraint = NSLayoutConstraint(item: content, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0) 
    view.addConstraint(bottomConstraint) 

let trailingConstraint = NSLayoutConstraint(item: content, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Trailing, multiplier: 1, constant: 0) 
    view.addConstraint(trailingConstraint)   

    let heightConstraint = NSLayoutConstraint(item: content, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 100) 
    view.addConstraint(heightConstraint) 

在这里,你应该考虑holder而不是view

这种约束是中间视图。对于第一和最后一个视图的场景应该是不同的东西一样,

//Top constraint for first view should be like, 

    let topConstraintForfirstView = NSLayoutConstraint(item: content, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0) 
    view.addConstraint(topConstraintForfirstView) 

    //Bottom constraint for last view should be like, 

    let bottomConstraintForLastview = NSLayoutConstraint(item: content, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0) 
    view.addConstraint(bottomConstraintForLastview) 

你可以通过改变约束constant管理空间或距离。如果你想要20像素之间的垂直间距视图然后你的常数top constraints should be 20

你可以参考this answer作为参考。

不要给高度和底部。如果你给定高度,那么你不需要底部,如果你给底部,那么你不需要固定高度。

希望这将有助于:)

1

在我们的项目中,我们遇到了类似的问题,我们不得不大量的意见添加到使用编程方式添加约束的滚动视图的内容视图。为每个视图编写约束不仅使视图控制器变得臃肿,而且也是静态的。要添加另一个视图,我们必须再次编写约束条件。

我们最终创建了UIView的子类,现在为我们管理了这个子类。我们将其命名为NNVerticalStackView.h.m

这个类的要点是下面的方法。

-(void)addView:(UIView *)view 
    belowView:(UIView *)viewAbove 
    aboveView:(UIView *)viewBelow 
    withHeight:(CGFloat)height{ 

    view.translatesAutoresizingMaskIntoConstraints = NO; 
    [self addSubview:view]; 

    if(height != NNStackViewContentHeightMetric && height > 0) { 
     NSArray * heightConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[view(height)]" options:0 metrics:@{@"height":@(height)} views:NSDictionaryOfVariableBindings(view)]; 
     [view addConstraint:heightConstraint.firstObject]; 
    } 

    NSArray * defaultConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[view]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)]; 
    NSLayoutConstraint * upperConstraint,* lowerConstraint; 

    if(viewAbove==self) { 
     [self removeConstraint:_topConstraint]; 
     upperConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[view]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)].firstObject; 
     _topConstraint = upperConstraint; 
    } 
    else 
     upperConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[viewAbove]-0-[view]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view,viewAbove)].firstObject; 

    if(viewBelow==self) { 
     [self removeConstraint:_bottomConstraint]; 
     lowerConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[view]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)].firstObject; 
     _bottomConstraint = lowerConstraint; 
    } 
    else 
     lowerConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[view]-0-[viewBelow]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view,viewBelow)].firstObject; 

    [self addConstraints:defaultConstraints]; 
    [self addConstraints:@[upperConstraint,lowerConstraint]]; 
} 

对于最顶部的视图,viewAbove是容器视图(即self),其他明智它代表了在视图的视图以上添加。 对于最下面的视图,viewBelow是容器视图,其他视图是当前视图下方的视图被添加的视图。

因此,对于这个子类,您打算做的事情可以很容易地编码为。

let N = 4 
let holder = NNVerticalStackView(frame: CGRectMake(0, 0, someWidth, CGFloat(N) * 100.0)) 
for _ in 0...N { 
    let content = UIView(frame: CGRect.zero) //height should be 100 
    holder.insertStackItem(content, atIndex: 0, withItemHeight: 100.0) 
} 

对于偏移量,您可能需要更改自定义类以定义您自己的偏移量。

相关问题