使用情节提要设置标签文本时的短暂延迟

Posted

技术标签:

【中文标题】使用情节提要设置标签文本时的短暂延迟【英文标题】:Short lag when setting label text using storyboards 【发布时间】:2016-01-28 20:59:41 【问题描述】:

在我的应用程序中,我有一个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

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

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

问题如下: 有时(并非总是如此,而且不可重现!),在加载覆盖视图控制器时,标签在显示文本之前的几分之一秒内是 empty (就像我在情节提要中定义的那样) . 因此,在将实际数据加载到标签中之前,用户会在短时间内看到空标签。

如何解决此问题? 从情节提要实例化视图控制器后,是否可以在不使用Timing.performAfterDelay(0) 的情况下立即访问插座?

我们将不胜感激。

【问题讨论】:

【参考方案1】:

Outlets 设置在视图加载之后,即在视图控制器上调用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 应该负责设置其标签值,而不是从外部设置这些值。您可以通过属性或参数将所需的数据传递给方法等。

【讨论】:

您的编辑对我没有帮助,因为即使 MyOverlayViewController 自行设置其标签值,它仍然需要在此之前加载其视图(如您在答案中所述)。 实际上,我是说,例如,您应该像这样将数据传递给 MyOverlayViewControllervc.data = data,然后在 MyOverlayViewControllerviewDidLoad 方法,您应该同时设置titleLabelcountLabel。这样做的好处是您不必记住使用 let _ = vc.view 强制加载视图 使用viewDidLoadawakeFromNib 是更好的做法吗? viewDidLoad 中执行此操作,这样无论您是从 Nib 加载视图控制器还是以编程方式创建它都无关紧要。 viewDidLoad 在这两种情况下都会被调用。

以上是关于使用情节提要设置标签文本时的短暂延迟的主要内容,如果未能解决你的问题,请参考以下文章

如何使用情节提要设置包装文本 UILabel Xcode

如何使用情节提要在 Tableview Cell 中为 2 个标签和一个图像视图设置约束?

使用情节提要中的属性字符串本地化 UILabel

标签栏项目未显示在情节提要中

使用情节提要创建的没有标题的自定义 UITabbarItem

如何仅使用一个情节提要为所有 iPhone 设备设计自动布局约束?