問題描述
我在我的應用程序中發現了一個奇怪的行為,其中連接的 IBOutlet
在我的視圖控制器中對 viewWillAppear:
和 的調用之間具有其連接的視圖框架viewDidAppear:
.這是我的 UIViewController
子類中的相關代碼:
I have discovered a strange behavior in my application, where a connected IBOutlet
has its connected view's frame between the calls in my view controller to viewWillAppear:
and viewDidAppear:
. Here is the relevant code in my UIViewController
subclass:
-(void)viewWillAppear:(BOOL)animated {
NSLog(@"%@", self.scrollView);
}
-(void)viewDidAppear:(BOOL)animated {
NSLog(@"%@", self.scrollView);
}
以及生成的日志輸出:
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 44; 320 416); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
這清楚地表明框架在兩次調用之間發生了變化.我想在 viewDidLoad
方法中對視圖進行設置,但如果內容在屏幕上之前無法更改,那似乎毫無用處.會發生什么?
Which clearly shows that the frame is changing between the two calls. I wanted to do setup with the view in the viewDidLoad
method, but if the content is not available for me to change until it is on the screen, that seems pretty useless. What could be happening?
推薦答案
Autolayout
對我們設計和開發視圖 GUI 的方式進行了巨大改變.主要區別之一是 autolayout
不會立即更改我們的視圖大小,而是僅在觸發時,即在特定時間,但我們可以強制它立即重新計算我們的約束或標記它們作為布局的需要".它的工作方式類似于 -setNeedDisplay
.
對我來說最大的挑戰是要理解并接受這一點,我們不再需要使用自動調整大小的蒙版,而框架在放置我們的視圖時已成為無用的屬性.我們不再需要考慮視圖位置,但我們應該考慮我們希望如何在彼此相關的空間中看到它們.
當我們想要混合舊的自動調整大小蒙版和自動布局時,就會出現問題.我們應該盡快考慮自動布局的實現,并盡量避免在基于自動布局的視圖層次結構中混合舊方法.
擁有一個僅使用自動調整大小掩碼的容器視圖是可以的,例如視圖控制器的主視圖,但如果我們不嘗試混合使用會更好.
我從未使用過故事板,但很可能它是正確的.使用自動布局,您的視圖框架在自動布局引擎開始計算時設置.嘗試在視圖控制器的 - (void)viewDidLayoutSubviews
方法的 super 之后詢問同樣的問題.
當自動布局引擎完成計算視圖的幀時調用此方法.
Autolayout
made a huge change in how we design and develop the GUI of our views. One of the main differences is that autolayout
doesn't change our view sizes immediately, but only when is triggered, that means at a specific time, but we can force it to recalculate our constraints immediately or mark them as "in need" of layout. It works like -setNeedDisplay
.
The big challenge for me was to understand and accept that, we do not need to use autoresizing masks anymore, and frame has become a useless property in placing our views. We do not need to think about view position anymore, but we should think how we want to see them in a space related to each other.
When we want to mix old autoresizing mask and autolayout is when problems arise. We should think about autolayout implementation really soon and try to avoid to mix the old approach in a view hierarchy based on autolayout.
Is fine to have a container view that uses only autoresizing masks, such as a main view of a view controller, but is better if we do not try to mix.
I never used storyboard, but most proably it is correct. Using Autolayout, frame of your views are set when the autolayout engine starts its calculation. Try to ask the same thing right after super of - (void)viewDidLayoutSubviews
method of your view controller.
This method is called when the autolayout engine has finished to calculate your views' frames.
這篇關于viewWillAppear: 和 viewDidAppear: 之間的視圖框架變化的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!