1

UIView在将其添加到显示的视图之前,有没有办法从 UI 线程外部操纵未显示的大小?

在处理一些异步 iOS 代码时,我想我会尝试构建一个异步方法,该方法UIView稍后会显示 [在 UI 线程上]。在这种情况下,这似乎是“陷阱”,这是UILabel我想给它一个从StringSizecall派生的预定帧大小的地方。不幸的是,首先调用的UIView构造函数。RectangleF frameUIApplication.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);
});

我已经决定让我的代码更具体到手头的情况,并使用 aTask<string>代替,让显示代码(在 UI 线程上运行)处理视图创建,但很高兴知道这是否可能,因为它将使我正在编写的代码更具可扩展性。

4

1 回答 1

2

UIKit 不是为在主线程之外使用而设计的。

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

于 2013-01-17T20:57:17.037 回答