在将UI线程添加到显示的视图之前,有没有办法在UI线程外部操纵未显示的UIView
的大小?
在处理一些异步iOS代码时,我想我会尝试使用异步方法构建一个UIView
,稍后会在[UI线程]上显示。在这种情况下,这似乎是“陷阱”,它是一个UILabel
,我想给它一个从StringSize
call派生的预定帧大小。不幸的是,UIView
构造函数首先调用RectangleF frame
调用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
设置为所需大小,UIView.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线程上运行)处理视图创建,但它会很好要知道这是否可行,因为它会使我编写的代码更具可扩展性。
答案 0 :(得分:2)
UIKit is not designed to be used outside of the main thread.
当忽略此规则时,我看到一些奇怪的行为蔓延,所以我强烈建议不要这样做。