2013-05-28 122 views
7

大家都知道你不能相信UIViewController init/viewDidLoad方法的幀大小;這樣的:UIViewController viewDidLoad不正確的寬度/高度

- (void)viewDidLoad: { 
    NSLog(@"%d", self.view.frame.size.width); 
} 

將打印在很多場合錯誤的大小(特別是它在橫向模式下幾乎打破)

這實際上將返回總是糾正結果,因此這是很好的佈局子視圖:

- (void)viewWillAppear: { 
    NSLog(@"%d", self.view.frame.size.width); 
} 

問題是viewWillAppears在每次出現視圖時被調用,所以它不適合分配或添加子視圖。所以你最終會在界面中聲明每個視圖,並且最終你會得到我不喜歡的巨大頭文件,因爲大多數項目在初始設置後不需要更多操作。

所以問題一是:有沒有更好的方式來處理子視圖定位?

問題二非常相關,比方說,我有一個包含各種其他子視圖的UIView的子類。我聲明它在我的界面,我分配/初始化它在我的init/viewDidLoad方法。

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    ... 
    menu = [[SNKSlidingMenu alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
    ... 
} 

正如我們已經知道我們現在需要重新定位其在viewWillAppear中,以獲得更準確的讀數

- (void)viewWillAppear:(BOOL)animated{ 
    .... 
    menu.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
    .... 
} 

的問題是,當然所有的子視圖需要重新定位爲好。這是通過自動調用的layoutSubviews函數完成的,但是我們得到了同樣的問題:所有子視圖都需要在SNKSlidingMenu類的接口中聲明。是否有解決此問題的方法?

謝謝。

+1

使用自動佈局,還是設置自動調整遮罩? – jrturton

回答

7

如果您靶向的iOS 5.0或更高版本可以使用viewWillLayoutSubviewsviewDidLayoutSubviews進行更改。

至於你的第二個問題,如果你需要訪問除init之外的其他方法的實例變量,你需要保留它,我沒有看到它的問題。

但是,您可以嘗試使用自動佈局並設置子視圖之間的規則,以便它自動爲您佈局而無需保留參考。

+0

表示同意,但是,必須使用initWithFrame來初始化每個視圖非常愚蠢。看起來像很多重複的代碼給我,似乎迫使你使用大量的實例變量。自動佈局僅適用於較新的iOS。 – ksn

+0

舊的'autoresizingMask'對你來說可能已經足夠了。至於重複的代碼:如果你複製了很多代碼,你可以創建自定義的'UIView'子類,這樣你就不會複製,或者有幫助方法爲你創建視圖。如果你發佈更多的代碼,我們可能會幫助你更多。 – pgb

6

viewDidLoad只有被調用時,你的看法是創建,但很多事情可以影響frame的大小,並且它不會再次調用時frame變化。

相反:

  • viewDidLoad
  • 創建子視圖設置其大小在 viewWillLayoutSubviews

處理旋轉這裏看到一些額外的討論:https://stackoverflow.com/a/16421170/1445366

2

viewWillLayoutSubviewsviewDidLayoutSubviews可以解決這個問題。
但是這兩個方法會執行更多次。 這是我的代碼得到正確self.view.frame

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    ... 
    dispatch_async(dispatch_get_main_queue(), ^{ 
    // init you view and set it`s frame. this can get correct frame. 
    ... 
    } 
    ... 
} 
+0

這是爲我工作的唯一解決方案。雖然,它有點難看一些怪異初始視圖中dispatch_async踢之前第二彈出一個分裂 對於Swift4: \t \t DispatchQueue.main.async { \t \t} –