试想这样的一个需求场合,一个button靠右显示,而且距离superView的顶部和右边间距分别为10和5。以下图所示:布局
要实现这样的需求,若是不用自动布局技术,那么咱们能想到的就是老老实实的使用绝对布局的坐标计算来实现了,假如这个button宽高都是100,父视图的宽是300,那么这个button的坐标就是:(300-100-5,10)。但要是父视图的宽度变了,咱们还得从新计算一遍。颇为麻烦。atom
幸亏咱们有自动布局技术。要实现这样的需求仍是相对比较简单的。spa
既然咱们要实现这样的需求,并且这个需求其实也是具备广泛性的,那么咱们直接封装下好了。咱们给UIView添加两个扩展属性:horizontalAlignment和verticalAlignment。两个属性都是枚举。code
typedef NS_ENUM(NSInteger, UIViewVerticalAlignment) { UIViewVerticalAlignmentFill = 0, UIViewVerticalAlignmentCenter = 1, UIViewVerticalAlignmentTop = 2, UIViewVerticalAlignmentBottom = 3 }; typedef NS_ENUM(NSInteger, UIViewHorizontalAlignment) { UIViewHorizontalAlignmentFill = 0, UIViewHorizontalAlignmentCenter = 1, UIViewHorizontalAlignmentLeft = 2, UIViewHorizontalAlignmentRight = 3 }; @property (nonatomic,assign)UIViewHorizontalAlignment horizontalAlignment; @property (nonatomic,assign)UIViewVerticalAlignment verticalAlignment;
实现的思路以下:orm
我下面以水平停靠举例,对于水平停靠有四种状况,首先就是不停靠彻底的填充,也就是咱们把该subview的宽度跟superview的宽度绑定到一块儿。第二种状况是左边停靠,依次还有居中停靠和右边停靠。blog
对于非填充停靠,在宽度方面确定不能直接绑定到superview的宽度了,只能使用UIView的扩展属性size的宽度了。ip
如今以上述场景的实现为例,就是水平方向右边停靠。那么咱们只要把subview的NSLayoutAttributeRight跟superview的NSLayoutAttributeRight对齐就行了。代码以下:get
[self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeRight multiplier:1.0f constant:-margin.right]];
对于左边停靠和居中停靠无非就是对齐的属性不同。对于垂直停靠来讲也是这样。源码
完整的停靠代码以下:博客
UIEdgeInsets margin=self.margin; switch (self.verticalAlignment) { case UIViewVerticalAlignmentFill: { NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top-[view]-bottom-|" options:0 metrics:@{ @"top" : @(margin.top),@"bottom":@(margin.bottom)} views:@{ @"view" : self}]; [self.superview addConstraints:constraints]; } break; case UIViewVerticalAlignmentBottom: { [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-margin.bottom]]; } break; case UIViewVerticalAlignmentCenter: { [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0]]; } break; case UIViewVerticalAlignmentTop: { [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTop multiplier:1.0f constant:margin.top]]; } break; default: break; } switch (self.horizontalAlignment) { case UIViewHorizontalAlignmentFill:{ NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-left-[view]-right-|" options:0 metrics:@{ @"left" : @(margin.left),@"right":@(margin.right)} views:@{ @"view" : self}];//添加宽度的约束 [self.superview addConstraints:constraints]; } break; case UIViewHorizontalAlignmentCenter:{ [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0]]; } break; case UIViewHorizontalAlignmentLeft:{ [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeLeft multiplier:1.0f constant:margin.left]]; } break; case UIViewHorizontalAlignmentRight:{ [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeRight multiplier:1.0f constant:-margin.right]]; } break; default: break; }
对于停靠,咱们前面写的UIStackPanel和UIGridView势必也要支持的。所以我也修改了下原来的代码。
而后对于图中 的那个button的代码就是以下:
UIButton *btn=[[UIButton alloc] initWithSize:CGSizeMake(100, 100)]; [btn setBackgroundColor:[UIColor blueColor]]; btn.isBindSizeToSuperView=YES; [btn setTitle:@"button1" forState:UIControlStateNormal]; btn.horizontalAlignment=UIViewHorizontalAlignmentRight; btn.verticalAlignment=UIViewVerticalAlignmentTop; btn.margin=UIEdgeInsetsMake(10, 0, 0, 5); [self.view addSubview:btn];
至此这个系列的博客完结!