2009-07-09 134 views
28

摘要:UIViewController在初始化該視圖時應該如何知道其UIView實例的大小?何處確定UIView大小

UIView的專用初始化方法是initWithFrame:(CGRect)frame方法。這爲新創建的UIView設置了框架。如果請求該視圖控制器的視圖,則可以從UIViewController's loadView方法調用此方法。的UIViewController狀態相對於子類化和視圖大小的文檔:

當創建視圖 層次的意見,你應該總是設置您的看法 自動尺寸屬性。 當顯示 屏幕上的視圖控制器,其根視圖通常是 調整大小以適合可用的空間, 可以變化取決於 窗口的當前取向和 存在其他界面元素 如狀態欄的。

因此,UIViewController實例應該設置這些屬性。迄今爲止,迄今爲止,UIViewController並不需要知道其觀點是多大還是將會如此。

當請求UIViewController的視圖並且視圖屬性爲零時,將調用視圖控制器的loadView方法。現在有一個問題,因爲UIView需要初始化,但視圖控制器仍然不知道視圖應該是多大。你應該對這個觀點初始化多大?你在代碼中確定視圖大小?

你可以初始化一個零矩形視圖(CGRectZero):

- (void)loadView { 
    self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; 
} 

而讓主叫方設置視圖幀像這樣:

UIViewController *viewController = [[MyUIViewController alloc] init]; 
// next two lines are normally combined, but for clarity they are not now 
UIView *view = viewController.view; 
view.frame = CGRectMake(0, 0, 200, 200); 

這從視圖控制器請求視圖(viewController.view),並因此使用loadView方法加載其視圖。此loadView方法使用CGRectZero初始化視圖。然後調用者設置其框架(view.frame = ...)

問題是視圖上的框架屬性設置了兩次,如果您的自定義UIView正在做一些高級佈局,則可能會導致更多的雙重工作setFrame方法(例如放置和調整子視圖的大小)。你可以通過爲UIViewController創建一個專用的初始化方法來防止這種情況,該方法已經向調用者請求一個CGRect,你可以將它存儲在一個ivar中。在調用loadView方法時,您使用此ivar創建視圖。

這裏有什麼好方法?將視圖的框架設置兩次(初始化爲CGRectZero,然後設置),或者給UIViewController一個帶有CGRect的新的初始化方法(從而給它一個框架屬性)?或者我錯過了一些東西,還有其他的可能嗎?

回答

8

你不要必須使用指定的初始值設定項。只需使用[[UIView alloc] init]中的init即可。指定的初始化器必須從子類的初始化器中使用。

另一方面,設置兩次幀應該不會造成太大的傷害。在setFrame:執行很多任務是不尋常的。佈局通常在layoutSubviews完成,並且只執行一次。

+10

的UIView的init方法實際上具有零矩形 – drvdijk 2009-07-09 12:43:16

+0

現在我注意到調用initWithFrame,同時施加變換到一個視圖中, layoutSubviews被調用。考慮到我在視圖控制器的touchesMoved方法中應用了轉換,在layoutSubviews中做了很多工作也不會被推薦... – drvdijk 2009-07-15 12:28:19

0

我目前正試圖從UIViewController的子類來創建一個通用組件後,完成同樣的事情,來到注意到相當奇怪的事情:

的UIViewController有一個「的loadView」方法,你可能會覆蓋到(引用文檔)「這是子類應該創建自定義視圖層次的地方」。所以,我創建我的視圖層次結構,使用默認幀大小合成我的屏幕(因爲我可能不知道我應該在調用loadView時顯示的框架)。

但是,然後,根據什麼呼叫我正確設置幀大小?又名:我的視圖控制器在什麼時候知道它的視圖實際大小?

我是否必須在ViewController子類中創建一個「setFrame」,以便創建viewcontroller的對象應該調用?這似乎很奇怪。

drvdijk:你有解決你的問題嗎?

編輯:剛剛發現的UIViewController文檔此注: 注意:你不應該使用視圖控制器來管理意見只能填充其窗口,也就是說,只能由應用程序內容矩形定義的區域的一部分的一部分。如果您希望有一個由多個較小視圖組成的界面,請將它們全部嵌入到單個根視圖中,並使用視圖控制器來管理該視圖。

所以,似乎UIViewController主視圖總是全屏。期。

這對我來說確實存在一個問題,因爲我試圖創建一個自定義的UITabBarViewController(爲了能夠在tabbar中顯示自定義圖像,而不是藍色漸變):我的tabBarViewController應該顯示子視圖控制器到只有窗口...

0

您可能想要計算可用屏幕空間(取決於導航欄,選項卡欄和狀態欄等其他視圖的存在)的邊界。您可以將這些界限用於loadView中的[[UIView alloc] initWithFrame:]中的框架參數。

如果這是你想要的,那麼你可能會發現我的答案在這裏有用的東西: Determine the correct size in loadView