2012-10-26 28 views
37

我不知道是否有人知道這是爲什麼,當你設置一個子視圖的框架viewDidLoadviewWillAppear的更改不會在屏幕上影響之前正確設置框架,但如果你在viewDidAppear他們做設置呢?無法viewDidAppear

在我來說,我加載自定義的廈門國際銀行有兩個tableviews然後試圖將它們轉移下來viewDidLoad允許其在viewDidLoad添加另一種觀點的空間,因爲它並不總是必要的,以顯示它。

問題是當我在viewDidLoadviewWillAppear中設置幀時,它被設置在對象上,我可以通過打印出來看到它,但它不反映在屏幕上。將我設置的幀調用移動到viewDidAppear將導致一切按預期工作。

認爲我應該可以設置框架viewDidLoad是錯誤的嗎?當類或裝載然而沒有UI元素已經被初始化,並且因此任何試圖引用它們將被覆蓋在初始化過程,其中viewDidLoad中和viewDidAppear調用之間發生unavaliable

- (id)init { 
    if (self = [super initWithNibName:@"MyView" bundle:nil]) {} 

    return self; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.descriptionWebView = [[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)] autorelease]; 

    [self.view addSubview:self.descriptionWebView]; 

    self.tableView1.autoresizingMask = UIViewAutoresizingNone; 
    self.tableView2.autoresizingMask = UIViewAutoresizingNone; 

    [self.descriptionWebView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"...." withExtension:@"html"]]]; 

    table1LocationWithHeader = CGRectMake(self.tableView1.frame.origin.x, 200, self.tableView1.frame.size.width, self.tableView1.frame.size.height - 200); 
    table2LocationWithHeader = CGRectMake(self.tableView2.frame.origin.x, 200, self.tableView2.frame.size.width, self.tableView2.frame.size.height - 200); 

    //this will NOT work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    //this will NOT work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 


- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 

    //this WILL work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 


//I added these after comments for stack overflow users, it seems like viewDidLayoutSubviews is the best place to set the frame 

- (void)viewWillLayoutSubviews { 
    [super viewWillLayoutSubviews]; 

    //this will NOT work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 

    //this WILL work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 
+0

可能是你可以顯示你的代碼? – Nekto

+2

[UIViewController返回無效幀?]的可能重複(http://stackoverflow.com/questions/9539676/uiviewcontroller-returns-invalid-frame) –

+0

注意!你的viewWillAppear調用'[super viewDidAppear];'它看起來像複製粘貼錯誤。 – Speakus

回答

93

viewDidLoad中被調用。一旦所有的UI元素都已初始化並繪製viewDidAppear被調用。

viewDidLoad中 - 控制器的看法後調用加載到內存中

在這一點上的看法是不是視圖體系內的。

viewWillAppear - 通知視圖控制器其視圖即將添加到視圖層次結構中。

此外,該視圖尚未添加到視圖層次結構中。

viewDidAppear - 通知視圖控制器其視圖已添加到視圖層次結構中。

只有這樣纔會將視圖添加到視圖層次結構中。

更新

viewDidLayoutSubviews是最合適的地方來修改UI實際上出現在屏幕上了。

viewDidLayoutSubviews - 通知視圖控制器,其視圖只是佈置其子視圖。

+0

好吧,所以viewDidLoad和viewWillAppear是相當簡單的錯誤的地方嘗試修改框架。也許設置框架的正確位置實際上是viewWill/DidLayoutSubviews,我剛剛在Rob鏈接的問題中看到,因爲viewDidAppear似乎爲修改框架太晚了。我會試試看看它是否有效。 – nacross

+8

我剛試過,viewDidLayoutSubviews好像是設置框架的最佳位置。謝謝你幫我清楚了。 – nacross

+0

這並不能解釋爲什麼在'viewDidLoad'中設置幀值不起作用。實際上,我經常在'viewDidLoad'中設置幀,從來沒有問題。 – Sulthan

2

看到這個線程When is layoutSubviews called?
當使用自動佈局,框架並不自動調用layoutSubviews。這非常重要。從裁判:

  • init不會引起layoutSubviews被稱爲(杜)
  • addSubview:導致layoutSubviews被叫做視圖添加,它被添加到(目標視圖)的視圖,所有的目標的子視圖。 ...


如果您在viewDidLoad中添加子視圖,layoutSubviews會在viewDidAppear之前調用,並且您可以獲得正確大小的子視圖。但是如果你什麼都不做,layoutSubviews將在viewDidAppear之後被調用。這取決於你的代碼。

0
在viewWillAppear中

()

只需調用layoutIfNeeded()一次,你想獲得它的框架圖。

if tableView then tableView.layoutIfNeeded()for example