2012-10-14 39 views
0

我只是想到,我可能沒有這樣做的權利。我曾多次被告知,viewDidLoad方法在第一次參考self.view時被調用。因此,以下代碼哪裏編碼子視圖的位置和配置屬於一個UIViewController的UIView

- (id)initWithFrame:(CGRect)frame{ 
self = [super initWithNibName:nil bundle:nil]; 
if (self) { 

    self.view.frame = frame; 

    } 
    return self; 
} 

在執行viewDidLoad之後完成了幀分配。

因此,任何在viewDidLoad之內對self.view.frame的引用都不會引用正確的幀。更重要的是,如果我在主視圖(self.view)內的子視圖中使用autoresizingMask(struts和spring),則任何比例間距都將基於錯誤的初始比例。關於autoresizingMask的文檔狀態如下:

當沿同一軸設置了多個選項時,默認行爲是在可變部分之間按比例分配大小差異。

什麼是正確的方式來配置UIViewController的視圖?是否像在viewWillAppearviewDidAppear方法中配置和添加子視圖一樣簡單?

+0

或者您可以繼承UIView並使用layoutSubviews。 – Rakesh

+0

如果我爲我的子類UIViewController創建一個initWitFrame方法,是否有一個「內置」的方式,該控制器的視圖用該框架初始化?我不這麼認爲,但視圖框架是如何初始化的?現在,我從法拉爾的方法調用中保存了幀,並在viewDidLoad中設置了視圖幀。我認爲這有點馬虎。 – Jim

+0

根據你的自定義'initWithFrame:'方法,你正在初始化視圖控制器,然後在分配視圖控制器的視圖之前設置視圖的框架(它並不指向任何特定的視圖)。所以你應該先設置視圖,然後設置框架。 – Rakesh

回答

0

當您將其view設置爲UIViewController時,如果該視圖尚未實例化(這是您第一次提出要求),則需要創建它(°)。

當一個視圖控制器需要實例其觀點:如果一個XIB與您UIViewController相關

  • ,則畫面從XIB加載。這意味着XIB文件是非存檔的,並且XIB中描述的所有對象都被分配/實例化。 XIB中的每個視圖因此通過使用alloc + initWithCoder: + autoreleaseNSCoder是解壓縮XIB的解碼器)來實例化。因此,您的每個意見都會收到initWithCoder:消息
  • 如果沒有你UIViewController有關廈門國際銀行,它會調用其loadView方法,讓您以編程方式創建視圖。在這種情況下,你在那裏編寫代碼來創建你的視圖,如[[[UIView alloc] initWithFrame:...] autorelease]。因此,您的視圖將通過代碼實例化並接收initWithFrame:消息,而不是initWithCoder:方法。
  • 其中UIViewController視圖已經或者通過取消歸檔XIB文件或通過在loadView代碼創建和實例化,所述視圖被加載和UIViewController接收viewDidLoad消息。

所以每個視圖收到任一initWithFrame:initWithCoder:(如果來自XIB創建)消息(如果由代碼創建)第一,然後一旦UIViewControllerview創建的所有視圖的層次結構,所述UIViewController本身收到viewDidLoad消息。這總是按照這個順序。


@implementation YourCustonUIView 
- (id)initWithCoder:(NSCoder*)decoder 
{ 
    // here the view is being allocated from the XIB. "alloc" as been called, "initWithCoder" is in progress 
    // frame is not set at this line, but as soon as we call the super implementation… 
    self = [super initWithCoder:decoder]; 
    if (self) 
    { 
    // Here all the properties of the view set in the XIB file (thru the inspector) are now applied 
    // Including the frame of the view (and its backgroundColor and all what you set thru IB) 
    // so self.frame is initialized with the correct value here 
    } 
    return self; 
} 

- (id)initWithFrame:(CGRect)frame 
{ 
    // here the view is being allocated from code. "alloc" as been called, "initWithFrame" is in progress 
    // self.frame is not set at this line, but as soon as we call the super implementation… 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
    // Here the view is initialized with its frame property 
    // so self.frame is initialized with the correct value here 
    // and you can initialize every other property from here 
    } 
    return self; 
} 
@end 

@implementation YourCustomUIViewController 
-(void)viewDidLoad 
{ 
    // At that point, the view of your UIViewController has been loaded/created 
    // (either via XIB or via the loadView method), so either its initWithCoder (if via XIB) 
    // or its initWithFrame (if via loadView) has been called 
    // so in either case, its frame has the right value 
} 

/* 
// In case your YourCustomUIViewController does not have a XIB associated with it 
// You have to implement this method to provide a view to your UIViewController by code 
-(void)loadView 
{ 
    // Create a view by code, and give it a frame 
    UIView* rootView = [[UIView alloc] initWithFrame:CGRectMake(0,0,..., ...)]; 
    rootView.backgroundColor = [UIColor redColor]; // for example 
    self.view = rootView; 
    [rootView release]; 

    // at the end of this method, self.view must be non-nil of course. 
} 
*/ 
@end 

(°),另一種可能性是,該觀點已被實例化,但後來解除了分配的,因爲你收到了內存不足的警告,而你的觀點是在屏幕上不那麼所使用的內存視圖已被回收。但無論如何,該視圖因此尚未加載並且必須被加載/創建

+0

由於我從一個子類UIViewController工作,我不知道如何到達其視圖初始化的位置。沒有[super initWithFrame ...]。這不是班級的一部分。 – Jim

+0

當然沒有。你看到我的代碼片段嗎? 'initWithFrame:'和'initWithCoder:'是'UIView'的方法,而不是'UIViewController'。 (事實上​​'initWithFrame'是'UIView'和'initWithCoder:'在'NSCoder'協議的一個方法中的一種方法,UIView'符合這個方法。這就是爲什麼我把這些方法放在'@implementation YourCustonUIView'中的例子。請閱讀我在我的答案中再次解釋的內容:''initWithFrame:'或'initWithCoder:'方法在你的'UIView'實例上被調用,而'viewDidLoad'方法在你的'UIViewController'上被調用。 – AliSoftware

+0

謝謝。我想,我沒有向下滾動。 (仍然習慣於使用新操作系統進行反轉滾動。) – Jim

相關問題