2010-02-13 23 views
3

我發現了一個奇怪的行爲,並想解釋我在做什麼說法,是錯誤的。的UIViewController與initWithNibName創建:包:或通過一個IBOutlet表現不同

在AppDelegate類一個新創建的WindowBased項目,我加入一個UIViewController的窗口。
我可以用兩種不同的方法:
- 帶一個IBOutlet。在IB中,我簡單地實例化了一個UIViewController,將它的類設置爲TestViewController並連接它(代碼的場景A)。
- 用代碼創建UIViewController(場景B)。

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

#define USE_IBOUTLET YES // Comment this line to switch to scenario B 

#ifdef USE_IBOUTLET 
    // Scenario A 

    [window addSubview:theTestViewController.view]; 
    [window makeKeyAndVisible]; 
#endif 


#ifndef USE_IBOUTLET 
    // Scenario B 

    TestViewController *theTestViewControllerProgrammatically; 

    theTestViewControllerProgrammatically = [[TestViewController alloc] initWithNibName:nil bundle:nil]; 

    // According to Apple: "It is a good idea to set the view's frame before adding it to a window.", so let's do it 
    [theTestViewControllerProgrammatically.view setFrame:[[UIScreen mainScreen] applicationFrame]]; 

    [window addSubview:theTestViewControllerProgrammatically.view]; 

    [window makeKeyAndVisible]; 
#endif 
} 

由於我沒有在IB中做任何定製的對象,我應該在這兩種情況下都有相同的行爲。

情景A,使用IBOutlet按預期工作。
但方案B具有以下問題:
- 的視圖不是在正確的位置(20個像素高,並且由所述狀態欄覆蓋)。
- 視圖無法正確調整大小(例如,嘗試切換「來電狀態」欄中的內容)

爲什麼?

項目的Zip文件在這裏,如果你想重現該問題:http://dl.dropbox.com/u/1899122/code/ProtoWindowBasedStrangeness.zip

回答

2

這是要健全我囉嗦的答案後真的​​很傻,但您遇到的問題很簡單修復(編程)。

這條線:

[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]]; 

實際上應該是:

[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]]; 

你了,不是你編程創建的設置通過IB設定爲VC框架。

無論如何 - 值得注意的是,我的所有評論仍然適用!還有,你必須做的編程方式,如果你不使用IB的控制器對象的幾件事情(例如,設置導航欄項目)

保羅

+0

正確。好的趕上:)我編輯了問題鏈接的問題和zip文件的內容。 – Guillaume 2010-02-24 16:04:46

0

大概在查看不知道一個狀態欄存在的情況B。您需要相應調整其大小並調整其位置以考慮狀態欄。這是通過更改UIView的框架(大小)和邊界(位置)屬性完成的。

+0

但是,爲什麼?在IB中創建一個對象並通過IBOutlet機制獲取它,而不是在代碼中創建相同的對象之間有什麼不同? Interface Builder中完成的對象絕對不是自定義的。 – Guillaume 2010-02-13 14:16:17

1

我一直有在一個非常類似的問題給你我注意到VC對象都不盡相同!我遇到的問題是設置導航欄項目,我似乎無法做到這一點,當文件的所有者是一個視圖控制器對象,我編程實例化。它只有在我解析IB的控制器對象時纔有效。

我下載了你的項目,有一個玩弄它,它讓我思考一些更多地瞭解可能什麼。我想我可以提供一個合理的答案,但不知道如果有一個簡單的解決方案...

我相信這是怎麼回事的是,蘋果已經創建了IB一些稍微更專業的這些控制器對象。一個建議可能是這樣的:IB VC對象有一個可以設置的屬性,對於UIViewController類我沒有直接的對應屬性,所以IB的控制器對象可能有一些額外的功能,即非IB UIViewController子類不能利用。鑑於.xib中的對象是完整的「凍幹」對象,Apple可能包含了我們在其IB版本中無法看到或使用的各種私有屬性 - 這可能會影響對象初始化的方式。

例如,在您的MainWindow.xib中,選擇IB VC對象,您可以從Inspector Palette上設置屬性,例如「調整從NIB查看視圖」。如果您取消選中並重新運行您的應用程序,則會看到VC完全按照它在場景B中的樣子顯示。由於您無法從File's Owner屬性中檢查此項目(即使它是作爲UIViewController ),您無法利用視圖控制器正在執行的任何操作來爲您提供所需的行爲。

這樣做的結果是,當您使用TestViewController.xib在代碼中初始化您的VC對象時,沒有設置VC的IB特定屬性,因此創建了一個bog標準的UIViewController,所以像「Resize從NIB查看「屬性並設置導航項目必須自己實施。

我還沒有找到一種方法來利用IB的視圖控制器使用initWithNibName:bundle:nibBundle(我猜這是我們無法訪問的所有私人東西)實例化的功能,但希望這可能有給你一個出發點...

當然,我可能是完全錯誤的,有人會讓我看起來像一個完整的白癡!

保羅

+0

我想我已經意識到了這個問題,如果你有興趣,看看我自己的問題的答案來繼承UIViewControllers。 – Paul 2010-02-15 21:25:44

+0

保羅,感謝您指出您的問題。在你的回答中,你完成了「如果你試圖以編程方式實例化一個對象而不是使用出口到IB對象,準備實施IB版本可能爲你提供的一些初始化......」。這種特定背景下的代碼是什麼? – Guillaume 2010-02-18 10:32:31

相關問題