你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS9之UIStackView體驗,無需任何約束

iOS9之UIStackView體驗,無需任何約束

編輯:IOS開發綜合

Apple在2012年推出AutoLayout,以前很排斥,現在用的飛起啊,2014年推出了Size Class,2015年又推出UIStackView,他提供了一組接口用於平鋪一行或者一列的的視圖組合.對於嵌入StackView的視圖,我們無需在進行任何約束了,UIKit已經幫忙最好了一切約束布局,也就是能自動適應不同屏幕.而且你可以在一個StackView內嵌入多個StackView來完成更為復雜的界面要求,簡單來說,他節省了很大一部分時間給每個UI元素創建約束,它繼承UIView,因此也會有很酷炫的動畫.

 

示例 1

\

示例 2

\

示例 3

\

 

 

看完圖後來聽我瞎BB幾句

 

先看下面一組圖

 

\

一般來講用約束布局完之後,又來一個需求,需要在中間再插入一個控件,那麼你肯定是這樣的

\咱們只能把原先的約束全部拆掉,然後重新插進新的約束,對於Autolayout沒那麼精通的我來說簡直是要命啊!!!

 

OK ,今天來簡單介紹下UIStackView的用途

StackView其實一個視圖容器(需要注意的是,他是一個不會被渲染的UIView的子類,他和其他UIView不同,不會被渲染到屏幕上,這意味著設置其BackgroundColor和重載drawReck:方法都不會產生任何效果),它會對它的子視圖根據一定規則自動布局,將子視圖按棧的排列方式進行布局,並且有幾個主要的屬性

1.Alignment屬性決定了Stack View如何沿它軸向的垂直方向擺放它的subview。對於一個垂直的Stack View,這個屬性可以設置為Fill、Leading、Center和Trailing

Fill

\

Leading

\

Center

\

Trailing

\

 

2.Distribution屬性決定了其子視圖的分布比例

Fill:默認分布方式

Fill Equally:子視圖的高度或寬度保持一致

Fill Proportionally:stackView自己計算出它認為合適的分布方式

Equal Spacing:子視圖保持同等間隔的分布方式

Equal Cenerting:每個子視圖中心線之間保持一致的分布方式

 

 

示例1分析

首先創建一個工程,在IB文件中右下角搜索StackView,會出現一個Horizontal和Vertical的兩個控件,一個是水平一個垂直布局

\

我們要一個水平布局的測試下,拖進工程裡面,上面已經提到不需要任何約束,但是需要給StackView設置如下約束給StackView設置距左,距上,距右的間距,使其頂在屏幕上方

設置高度為SuperView的0.7倍

\ \

 

然後我們往StackView裡面拖三個ImageView,每個ImageView的設置如下

\

 

再把StackView的參數設置為如下,注意看這裡的黃色小箭頭,有的話可以點進去看看什麼錯誤,如果出現紅色的箭頭那也點進去,可以選擇自動修復或者根據提示更改,沒有箭頭才是正確的配置

 

\

 

 

 

根據提示修改之後沒警告了,效果就出來了,我們根本不需要給單獨的ImageView設置約束

 

\

 

上層圖片已經完成了,咱們再加點文字什麼的,現在先不拖UIStackView,先拖兩個UILabel,一個顯示名字在上面,一個現實描述在下面,拖完之後咱們同事按住Command選中兩者,然後按下右下角的棧堆視圖控制快捷鍵,他們就被加入一個UIStackView管理了(如果要解散這個Stack,請先選擇需要解散的Stack,然後按住ALT + 鼠標左鍵,點擊Unembed即可),默認是垂直的,然後繼續選擇StackView的屬性Axis(方向),Alignment(對齊方式),Distrubution(填充方式),Spcaing(間隙)進行布局

\

 

 

上圖已經有一個Stack了,咱們現在要做的就是再嵌套一個,看下圖示例

 

\

 

 

那麼再嵌套一個也是一樣的套路,拖到想要的位子就好了 ,總體結構如下

 

\

 

正如你所看到的,我們只需要拖動UIStackView(僅僅設置容器的約束就好),裡面的空間只要設置他的幾個屬性值就

能達到精確布局,省去了單個UI空間的約束設置,經過我的\\\加了點代碼,還能實現簡

單的動畫

 

 

@property (weak, nonatomic) IBOutlet UIImageView *imageView1;
@property (weak, nonatomic) IBOutlet UIImageView *imageView2;
@property (weak, nonatomic) IBOutlet UIImageView *imageView3;
@property (nonatomic,assign) BOOL isLarge;

 

 

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.title = @"Command + →或者點圖片有動畫";
    for (NSInteger i = 0; i < 3 ; i ++)
    {
        UIImageView *imageView = [self valueForKey:[NSString stringWithFormat:@"imageView%zd",i + 1]];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickImageView:)];
        imageView.userInteractionEnabled = YES;
        [imageView addGestureRecognizer:tap];
    }
}

 

- (void)clickImageView:(UITapGestureRecognizer *)tap
{
    long long tag = tap.view.tag;
    self.isLarge = !self.isLarge;
    switch (tag) {
        case 1000:
            if (!self.isLarge)
            {
                [UIView animateWithDuration:0.5 animations:^{
                   
                    self.imageView2.hidden = NO;
                    self.imageView3.hidden = NO;
                }];
            }
            else
            {
                [UIView animateWithDuration:0.5 animations:^{
                    
                    self.imageView2.hidden = YES;
                    self.imageView3.hidden = YES;
                }];
            }
            
            break;
        case 1001:
            if (!self.isLarge)
            {
                [UIView animateWithDuration:0.5 animations:^{
                    
                    self.imageView1.hidden = NO;
                    self.imageView3.hidden = NO;
                }];
            }
            else
            {
                [UIView animateWithDuration:0.5 animations:^{
                    
                    self.imageView1.hidden = YES;
                    self.imageView3.hidden = YES;
                }];
            }
            
            break;
        case 1002:
            if (!self.isLarge)
            {
                [UIView animateWithDuration:0.5 animations:^{
                    
                    self.imageView2.hidden = NO;
                    self.imageView1.hidden = NO;
                }];
            }
            else
            {
                [UIView animateWithDuration:0.5 animations:^{
                    
                    self.imageView2.hidden = YES;
                    self.imageView1.hidden = YES;
                }];
            }
            
            break;
            
        default:
            break;
    }
}

 

 

正常的時候

 

\

 

橫過來(CMD + →)

 

\

 

\\\\\第一個Demo差不多就這樣,大家可以去試試,非常容易

 

 

示例2分析

通過UIStackView給UITableView布局cell

創建一個UIImageView 一個UILabel 一個UIButton

給這三個東西集合成一個UIStackView 給Stack設置好約束的時候,竟然出現紅色警告

\ \ \

 

當時我真的慌了,經過我不洩努力

先看警告圖

\

 

 

決定StackView如何將它的子視圖沿軸向分布的屬性是他的distribution屬性。當這個屬性默認是Fill的時候,子空間會填充滿整個容器,StackView會拉伸其中一個使其充滿整個屏幕,尤其是水平內容優先級較低的空間,如果全部一樣的優先級,那麼默認伸縮第一個控件,就和上面的圖一樣,左側圖片被拉伸了

 

下圖所示,上面那個是內容吸附,下面的是抗壓阻力,越高就越不容易被外界約束破壞控件的內容

具體請見Hugging priority和compressing resistance priority的圖解

\

 

這三個空間默認都是251 和 750,我們改成這樣左 中 右分別是 ImageView UILabel UIButton

\ \ \

 

運行起來的效果圖

\

 

效果不是你想要的???\\\

 

好吧,咱們把UIImageView和UIButton的優先級對掉下 圖片順序是 UIImageView UILabel UIButton對應的優先級

\ \ \

 

再運行

\

這回滿意了吧!!!

 

示例3就不解釋了,基本是一個套路,看完上面兩個可以簡單玩玩示例3的效果.博主智商

有限,只能給出簡單的Demo,各位腦洞大開可以再自己去試試其他的

 

Over~~~~~~

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved