使用故事板设置标签文本时出现短暂延迟

时间:2016-01-28 20:59:42

标签: ios swift uiviewcontroller storyboard uistoryboard

在我的应用程序中,我有一个mainViewController,其中包含一些内容。在某些时候,我从故事板加载了一个覆盖视图控制器。叠加视图控制器小于屏幕,显示在mainViewController的顶部。我用以下方式初始化它:

class MyOverlayViewController {
    @IBOutlet var textLabel: UILabel!
    @IBOutlet var countLabel: UILabel!

    static let storyboard = UIStoryboard(name: "...", bundle: nil)

    // Return a new view controller
    class func newViewControllerWithData(data: AnyObject) -> UIViewController {
        let vc = storyboard.instantiateViewControllerWithIdentifier("MyOverlayViewController") as! MyOverlayViewController

        Timing.performAfterDelay(0) {
            vc.titleLabel.text = data[...] // Load title label text
            vc.countLabel.text = data[...] // Load count label text
        }

        return vc
    }
}

我无法在方法newViewControllerWithData中立即设置标签文本,因为这会产生以下错误:fatal error: unexpectedly found nil while unwrapping an Optional value.因此,在此方法中立即访问标签时,标签为nil

当从storyboard实例化视图控制器时,似乎两个标签出口没有立即加载,因为这需要(非常)短的时间。

因此,我使用我的方法Timing.performAfterDelay(0),它在下一个运行循环周期后执行代码(它启动一个持续时间为0的定时器并执行代码作为回调)。代码是(我已经检查过)在主线程上执行。

问题如下:
有时候(不总是,并且不可重现!),在加载覆盖视图控制器时,标签在为空(就像我在故事板中定义它们)之前,它们在显示文本之前。 因此,在将实际数据加载到标签之前,用户会在短时间内看到空标签。

如何解决此问题?
从故事板中实例化视图控制器后,是否有可能以某种方式立即访问出口,而不使用Timing.performAfterDelay(0)

帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

在视图加载后,即在视图控制器上调用viewDidLoad时,将设置为。但是,直接调用它vc.viewDidLoad()将无效,您必须访问视图控制器的视图,如let dummyVariable = vc.view。这是强制加载视图然后设置标签值的代码。

class func newViewControllerWithData(data: AnyObject) -> UIViewController {
    let vc = storyboard.instantiateViewControllerWithIdentifier("MyOverlayViewController") as! MyOverlayViewController
    let _ = vc.view // force load the view
    // now set your outlets as you please
    vc.titleLabel.text = data[...] // Load title label text
    vc.countLabel.text = data[...] // Load count label text
    return vc
}

注意:但这并不是一个好习惯。 MyOverlayViewController 应负责设置其标签值,而不是从外部设置这些值。您可以通过属性或参数将所需数据传递给方法等。