2015-07-10 81 views
10

我剛剛在Facebook SDK for iOS中看到,他們稱[super layoutSubviews];最後,而不是layoutSubviews方法的開始。 據我所知,我們應該始終把它作爲第一行。 這樣做是否可以爲UI創建一些意想不到的行爲?調用[super layoutSubviews]的正確方法是什麼?

- (void)layoutSubviews 
{ 
    CGSize size = self.bounds.size; 
    CGSize longTitleSize = [self sizeThatFits:size title:[self _longLogInTitle]]; 
    NSString *title = (longTitleSize.width <= size.width ? 
        [self _longLogInTitle] : 
        [self _shortLogInTitle]); 
    if (![title isEqualToString:[self titleForState:UIControlStateNormal]]) { 
    [self setTitle:title forState:UIControlStateNormal]; 
    } 

    [super layoutSubviews]; 
} 
+0

「據我所知,我們應該始終把它作爲第一行」你怎麼知道「? – matt

+1

@matt,我相信這是iOS開發者社區使用的約定,因爲超類可能會有一些默認/常規設置,可能會影響我們的自定義佈局不被應用(如果我們在方法結束時執行此操作)。與在構造函數/初始化器中作爲第一行調用super相似。 – ppalancica

+1

「超級類可能有一些默認/常規設置,可能會影響我們的自定義佈局不被應用(如果我們在方法結束時執行此操作)」。是的,這是絕對正確的。但這與「永遠應該」不一樣。 – matt

回答

7

按照UIView Class Reference

此方法的默認實現不執行在iOS 5.1和更早版本罷了。否則,默認實現使用您設置的任何約束來確定任何子視圖的大小和位置。

因此,Facebook的SDK示例應用程序在其執行結束通話[super layoutSubviews]可以與應用中開始之前的iOS 5.1建立一個IOS版本的神器。

對於更新版本的iOS,您應該在實施開始時致電[super layoutSubviews]。否則,在您執行自定義佈局後,超類將重新排列您的子視圖,實際上忽略了您對'layoutSubviews()'的實現。

2

如果視圖的內在內容大小將發生更改,則始終需要致電[super layoutSubviews]。如果您更改按鈕的標題,則UIButton的固有內容大小將會更改,因此最後一次調用將會更改。

對於[super layoutSubviews]的第一個調用總是需要的,因爲iOS會根據約束更新佈局。 但是,實現您的樣品的技術最正確的方法應該是:

- (void)layoutSubviews 
{ 
[super layoutSubviews]; 
    CGSize size = self.bounds.size; 
    CGSize longTitleSize = [self sizeThatFits:size title:[self _longLogInTitle]]; 
    NSString *title = (longTitleSize.width <= size.width ? 
        [self _longLogInTitle] : 
        [self _shortLogInTitle]); 
    if (![title isEqualToString:[self titleForState:UIControlStateNormal]]) { 
    [self setTitle:title forState:UIControlStateNormal]; 
    } 

    [super layoutSubviews]; 
} 
+0

只是好奇:您是否在任何地方的文檔中備份了內部內容大小的聲明? – ndmeiri

+0

不幸的是,但如果你考慮一下:內部內容大小隻能用setNeedsLayout來更新,它直接調用layoutSubviews。如果在layoutSubviews中更改內部內容大小(更改按鈕標題),則如果[super layoutSubviews]將不會被調用,則容器(Button)無法正確應用這些更改。 – seeya

+0

@ndmeiri在iOS7上運行時,如果我只是首先調用[super layoutSubviews]:運行時發生錯誤:由於未捕獲異常'NSInternalInconsistencyException',終止應用程序,原因:'在執行-layoutSubviews之後仍然需要自動佈局。 {VIEW}的-layoutSubviews實現需要調用super。' – Matthew

4

外觀到代碼,[超級layoutSubviews]之前,是不是該幀。所以把它放在最後也可以工作得很好。 我想編碼器必須根據一些規則檢查標題並修改標題,他認爲每次調用layoutSubviews都是一個正確的機會,所以他把代碼放在這裏。

相關問題