2015-09-02 31 views
5

試圖打破,我有一會兒一個問題,現在如何其視圖控制器的viewDidAppear之前確定的UIView大小

背景

假設我嘗試計算應該完全適合一個UIImage一個UIImageView,在故事板中受到約束。

imageView的內容不應該填充/方面適合...但完全適合框架。 因此我有一個方法,在我的viewController

- (UIImage *)calculatedImageForRect:(CGRect)imageRect 

問題

我要確保,該ImageView的已儘快視圖變得可見包含正確的圖像,所以也是在一個簡單的推送轉換。 此外,我不想多次生成UIImage,因爲它相對昂貴。

這將成爲與像iPhone6加設備,具有不同的屏幕分辨率

顯然在viewDidLoad幀未正確設置特別有趣。此時,幀被設置爲在故事板的預覽中 - 例如,設置代表IPhone5分辨率。 viewWillAppear也是如此。 這裏框架將例如是(10,10,300,100)< - 讓我們稱之爲錯幀

viewDidAppear該幀被正確(10,10,394,100)=的正確幀 < - 代替320點寬度,所述iPhone6Plus有414分。儘管如此,這已經太晚了,因爲視圖已經可見並且設置圖像會導致閃爍(空圖像>新生成的圖像)​​。

我知道正確的時間與幅度的工作是viewDidLayoutSubviews,這是第一個被稱爲與錯誤幀至少一次,然後在一個點上與正確幀。 但正如我所說的,我不想生成圖像多次,所以這裏的兩難境地:

我如何確定右幀之前,它是可見的?

當然,我可以通過使用UIImageView的尾部&前導約束來計算[UIScreen mainScreen]分辨率的正確幀,但它感覺很髒。

+0

所以你的問題的本質是,當你的視圖層次結構中的特定視圖(在這種情況下是UIImageView)最終設置爲正確的框架,但在它呈現在屏幕上之前,你想知道如何得到通知? – algal

+0

是的,這正是我想知道的 – MarkHim

回答

7

您不能使用viewDidLayoutSubviews的原因是,正如您所說,它可能會被多次調用。 layoutSubviews也是如此。

這是爲什麼?其中一個原因是,這是因爲基於約束的佈局是一個迭代過程,可能涉及多個過程。例如,我強制要求視圖V的佈局,該視圖在其視圖層次結構中包含子視圖W,其中包含子視圖X.對X佈局的第一個自動佈局計算可能會改變約束,然後需要重新計算W ,然後需要重新計算X.這與基於自動調整大小掩模的佈局基本不同,後者自上而下,因此外部視圖總是指定其子視圖的佈局。

但是,我認爲(但不是100%肯定),如果所有佈局代碼都正確實現,那麼這些多個佈局傳遞都應該在運行循環的一個回合內發生。也就是說,當您通過調用layoutIfNeeded來強制V上的佈局來啓動此過程時,則可以確定所有自動佈局佈局傳遞W和X已完成,一旦layoutIfNeeded返回。沒有「需要佈局」或「需要更新約束」標誌將被等待下一輪運行循環完成工作。

這可能指向您的解決方案。如果強制對層次結構中的頂級視圖進行早期佈局(例如,您要轉換到的視圖控制器的根視圖),那麼當該佈局過程完成時,將會有一個正確的框架,並且您可以使用該框架框架來生成您的圖像。

本質上,不是在最後可能的時刻做佈局,而是迫使它更早完成。然後,您可以知道何時完成,因爲您啓動了它並可以通過等待layoutIfNeeded退出來看到過程的結束。然後你可以觀察你關心的結果值。

+1

說實話,我沒有想到這會起作用 - 但它確實如此。我現在正在調用'viewWillAppear:'中的'layoutIfNeeded',正如你所描述的,之後所有的子視圖都被正確地佈置了。謝謝你的回答。 – MarkHim

+0

我活着去服務。 – algal

相關問題