2013-01-17 25 views
1

在將UI線程添加到顯示的視圖之前,有沒有辦法從UI線程外部操縱未顯示的UIView的大小?在UI線程之外創建一個未顯示大小的UIView?

在處理一些異步的iOS代碼時,我想我會試着讓一個異步方法構建一個UIView,稍後會在UI線程上顯示。在這種情況下,這似乎是「陷阱」,它是一個UILabel,我想給它一個從StringSize call派生的預定幀大小。不幸的是,首先需要RectangleF frameUIView構造函數調用UIApplication.EnsureOnUIThread

// Throws UIKitThreadAccessException on Frame-setting UILabel constructor. 
Task<UILabel> getView = Task.Factory.StartNew(() => { 
    //... Do some async fun (e.g., call web service for some data for someNSString) 

    SizeF requiredStringSize = someNSString.StringSize(someFont, new SizeF(maxWidth, float.MaxValue), UILineBreakMode.WordWrap); 
    RectangleF someViewFrame = new RectangleF(PointF.Empty, requiredStringSize) 
    return new UILabel(someViewFrame); 
}); 

因爲我並不真的需要這個任務執行的點設置有效的位置,我想我能避免設置在構造框架和設置的大小之後。不幸的是,您似乎只能通過整體修改UIView.Frame來設置大小。雖然無參數構造函數不會調用此UI線程,但只要我嘗試將Frame設置爲所需的大小,訪問器就會發生並且會崩潰。

// Also throws UIKitThreadAccessException, this time when setting the Frame directly. 
Task<UILabel> getView = Task.Factory.StartNew(() => { 
    //...do all the above stuff... 
    UIView someView = new UILabel(); 
    someView.Frame = new RectangleF(someView.Frame.Location, requiredStringSize); 
}); 

我已經決定把我的代碼更具體手頭的情況下,用一個Task<string>代替,讓顯示的代碼(UI線程上運行)處理視圖創建,但它會很高興知道這是否可能,因爲它會使我寫的代碼更具可擴展性。

回答

2

UIKit is not designed to be used outside of the main thread.

我見過此規則時忽略了一些奇怪的行爲蠕變,所以我強烈反對這項建議。

+0

我絕對看到bug的主要潛力。我有一個沉重的JavaScript背景,所以我非常習慣在渲染DOM之前在UI之外構建UI。當然,這些都在同一個線程上(並且增量的實時DOM更新會更慢),所以它可能是被鼓勵的唯一原因。這就是我想要在這裏應用的觀點,但它比任何重要的東西都更加好奇。 – patridge

+0

** strong ** ++除了努力解決這個問題之外沒有什麼可以解決的(看起來*只能在不同設備上失敗)。 – poupou

相關問題