在將UI線程添加到顯示的視圖之前,有沒有辦法從UI線程外部操縱未顯示的UIView
的大小?在UI線程之外創建一個未顯示大小的UIView?
在處理一些異步的iOS代碼時,我想我會試着讓一個異步方法構建一個UIView
,稍後會在UI線程上顯示。在這種情況下,這似乎是「陷阱」,它是一個UILabel
,我想給它一個從StringSize
call派生的預定幀大小。不幸的是,首先需要RectangleF frame
的UIView
構造函數調用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線程上運行)處理視圖創建,但它會很高興知道這是否可能,因爲它會使我寫的代碼更具可擴展性。
我絕對看到bug的主要潛力。我有一個沉重的JavaScript背景,所以我非常習慣在渲染DOM之前在UI之外構建UI。當然,這些都在同一個線程上(並且增量的實時DOM更新會更慢),所以它可能是被鼓勵的唯一原因。這就是我想要在這裏應用的觀點,但它比任何重要的東西都更加好奇。 – patridge
** strong ** ++除了努力解決這個問題之外沒有什麼可以解決的(看起來*只能在不同設備上失敗)。 – poupou