1. 程式人生 > >ios自動佈局的坑和與之有關的特殊坑

ios自動佈局的坑和與之有關的特殊坑

前行文

autoLayout自動佈局在ios開發中有其不可比擬的優勢,簡化的程式碼,讓後期維護變得更簡單。這裡不做autoLayout與autoResize的優勢分析,但是在開發過程中如果不注意就會遇到autoLayout意想不到的坑,下面稍微總結一下,

1、關於frame

用autoLayout和autoresize佈局的檢視,在UI重新整理後的frame上,是相同的,但是在沒有重新整理前是不同的。換句話說,用autoLayout佈局後,如果用程式碼更改其frame的話,在本次UI重新整理時會更新成你所設計的frame,然後在下一次UI重新整理完成的時候會變回你在storyboard裡所約束佈局的樣子,這種情況在使用tableview、collectionview的reloadData或textFiled時應有所注意,而歸根究底,是因為autoLayout限制的frame問題。
為什麼會是這樣,我們我們說一下controller的生命週期,init—初始化程式viewDidLoad—載入檢視viewWillAppear,這是VC物件的檢視即將加入視窗時呼叫;viewDidApper,這是VC物件的檢視已經加入到視窗時呼叫。而如果用autoLayout佈局時在viewDidLoad和viewWillAppear時,獲取到的是在storyboard裡的frame,而在wiewDidAppear中才是正確的frame。但是利用autoresizing是都可以獲取到在storyboard約束的frame的。所以在一點需要注意。

2、關於特殊坑

那麼,假如說我們設計好了檢視,在程式碼中需要獲取其frame,對於autoLayout的要在wiewDidAppear之後獲取,而用autoresing的方法,可以在任何時候獲取。那麼我們如果需要修改frame該怎麼辦,這裡就是特殊性
之所在。
1、所更改frame的檢視為單一檢視或者視圖裡沒有變化的元素,兩種自動佈局的方法都可以用程式碼更改frame。2、所更改frame的檢視不為單一檢視,在檢視變化中有例如textFiled,label的變化。則會產生問題,什麼問題,程式碼控制不了用autoLayout的frame,

labelView.frame=CGRectMake(0,200,self.view.frame.size.width,100); _showLable.text = @"你的名字";

就像這樣,用autoLayout佈局的labelView裡有個label,在改變其frame時同時改變label的值,就會出現label變化但frame不變化的情況,類似的如改變textFiled的。但是如果用autoresing方法佈局,就不會出現這種情況。怎麼辦,解決辦法就是用修改約束線
的方法更改用autoLayout佈局的labelView裡有個可變label的frame的方法。
_viewLable.constant = 100.f;
_showLable.text = @"你的名字";
總之,如何避免所說的佈局的坑,1、注意frame的呼叫方法 2、儘量不修改frame,若非要修改,那麼用autoresing的佈局方法,可以程式碼設定frame,用autoLayout的方法在所涉及檢視沒有變化的情況下可以程式碼設定frame的方式修改,關鍵點 如果所涉及的視圖裡面有可變的元件,如label的值,也就是label的佈局依賴於要改變的frame的檢視,那麼就用程式碼設定frame的方法是設定不了的,用約束線的方法。
後續,可以試一下以下設定1、分別用autoLayout佈局基於self.view的UIViewTextFiled和基於self.view一個子view的UIViewTextFiled,然後用程式碼更新其frame看看有什麼相同或不同。歡迎反饋探索。