IOS 自動佈局-UIStackPanel和UIGridPanel(五)

試想這樣的一個需求場合,一個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];

 

 至此這個系列的博客完結!

完整的源碼請點擊下載。

相關文章
相關標籤/搜索