在UI线程外创建一个不显示的,大小的UIView?

时间:2013-01-17 20:52:30

标签: xamarin.ios

在将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线程上运行)处理视图创建,但它会很好要知道这是否可行,因为它会使我编写的代码更具可扩展性。

1 个答案:

答案 0 :(得分:2)

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

当忽略此规则时,我看到一些奇怪的行为蔓延,所以我强烈建议不要这样做。