在上一篇博客中詳細的介紹了IOS開發中的相對布局和絕對布局,隨着手機屏幕尺寸的改變,在App開發中為了適應不同尺寸的手機屏幕,用自動布局來完成我們想要實現的功能和效果顯得尤為重要。本人更喜歡使用相對布局。在下面要學習的例子中暫且先用我們的StoryBoard來設置我們組件的約束,以后會在代碼中給我們的元素新建約束。iPhone4,5和將要發布的iPhone6的屏幕的大小都不一樣,所以屏幕的適配是我們搞App開發必須要考慮的問題。
我們要完成一個什么例子呢,先上兩張程序運行最終的結果圖,之后看着圖提出我們要實現的效果
界面要求:
1.下面刷新的按鈕在3.5和4.0寸屏上離下面的bottom的距離都是為20點。
2.根據網絡請求文字的內容的多少來動態的調整Lable的高度
3.當Label的高度變化時,下面的三個按鈕的位置也相對於Lable的位置變化
下面我們就以代碼結合着storyboard來實現上面的效果。
1.為了模擬網絡請求,我們需要新建一個SourceManager類,和SourceManagerDelegate. 我們請求資源的時候用到的是委托回調,關於委托回調的內容請參考之前的博客ObjC中的委托模式。在SourceManager類中有一個qingquWeibo的方法,用於模擬網絡請求。在SourceManagerDelegate協議中有一個-(void)sourceManager:(SourceManager *)sm didReceiveWeiboText:(NSString *)text; 用於回調。
SourceManager.h中的代碼如下:
1 #import <Foundation/Foundation.h> 2 3 @protocol SourceManagerDelegate; 4 5 @interface SourceManager : NSObject 6 //回調對象 7 @property(nonatomic,weak)id<SourceManagerDelegate>delegate; 8 //請求方法 9 -(void)qingquWeibo; 10 11 @end 12 13 14 //-----協議 15 16 @protocol SourceManagerDelegate <NSObject> 17 //source要回調的方法 18 -(void)sourceManager:(SourceManager *)sm didReceiveWeiboText:(NSString *)text; 19 20 @end
SourceManager.m的代碼如下:
1 #import "SourceManager.h" 2 3 @implementation SourceManager 4 5 -(void)qingquWeibo 6 { 7 8 NSString *str; 9 10 //隨機確定是那個字符串 11 int i = arc4random()%2; 12 if (i) 13 { 14 //模擬請求要返回的字符串1 15 str = @"iPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhoneiPhone"; 16 } 17 else 18 { 19 //模擬請求要返回的字符串2 20 str= @"iPhone"; 21 22 } 23 24 //回調方法,返回text 25 [self.delegate sourceManager:self didReceiveWeiboText:str]; 26 27 }
2.實現我們的模擬SourceManager的類以后就開始編寫我們的ViewController的類。
(1)給lable和lable下面的四個按鈕在storyBoard添加約束,步驟如下:
(2).給各個控件添加完約束后,我們需要在ViewController中添加我們要使用的控件和Label的垂直約束,代碼如下
1 //lable中的垂直約束,根據請求的text內容,用於動態的修改label的大小。 2 @property (strong, nonatomic) IBOutlet NSLayoutConstraint *lableVConstraint; 3 4 //label用於設置請求的文字內容 5 @property (strong, nonatomic) IBOutlet UILabel *myLabel; 6 7 //請求數據源的按鈕 8 @property (strong, nonatomic) IBOutlet UIButton *updateButton; 9 10 //sourceManagmer;獲取數據 11 @property (strong, nonatomic) SourceManager *sourceManager;
(3).在viewDidLoad里面配置我們的數據源
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //新建數據源 self.sourceManager = [[SourceManager alloc] init]; //注冊回調 self.sourceManager.delegate = self; }
(4).實現sourceManager要回調的方法,代碼如下
//sourceManage要回調的方法 -(void)sourceManager:(SourceManager *)sm didReceiveWeiboText:(NSString *)text { //根據text調節myLable的高度 //先移除myLabel的垂直布局,之后在賦新的值 [self.view removeConstraint:self.lableVConstraint]; //用字典設置字體的大小 NSDictionary * dic = @{NSFontAttributeName: [UIFont systemFontOfSize:17]}; //獲取在固定寬度區域內存放請求的文字需要的范圍 CGRect bounds = [text boundingRectWithSize:CGSizeMake(230, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil]; //創建新建垂直約束時的參數 NSString *string = [NSString stringWithFormat:@"V:[_myLabel(%lf)]", bounds.size.height]; //給myLabel中創建新的垂直約束 NSArray *constraint = [NSLayoutConstraint constraintsWithVisualFormat:string options:0 metrics:nil views:NSDictionaryOfVariableBindings(_myLabel)]; //更新垂直約束的值 self.lableVConstraint = constraint[0]; //添加新的約束 [self.view addConstraint:self.lableVConstraint]; //設置myLabel的值 self.myLabel.text = text; }
代碼說明:
1.在更新label的垂直約束之前先把原有的Constraint移除掉,注意:約束是加在約束組件的父類組件中。
2.獲取在固定寬度,特定字體時顯示text需要空間的大小,返回值是一個CGRect類型的變量。
3.把獲取區域的高度設置成我們Label的垂直約束的值。
代碼補充:
點擊刷新按鈕要出發的事件,點擊刷新按鈕會開啟請求,這樣回調才會有效。
1 //點擊按鈕的時候請求數據 2 - (IBAction)tapButton:(id)sender 3 { 4 //調用數據源的請求方法 5 [self.sourceManager qingquWeibo]; 6 }
就是全部代碼和步驟,歡迎批評指正。