Swift:Gui没有更新/太晚

时间:2017-06-17 20:09:54

标签: ios swift user-interface

我目前正在使用swift和xcode为iphone编写Quiz-App。由于一周我遇到了问题,我今天无法解决这个问题。

小背景资料:

所有问题都在线存储在服务器上,并及时下载。问题总是包含图像,因此加载它们需要一些时间。这就是为什么我在后台预加载下一个问题,而用户仍然在考虑当前的问题。因此我使用扩展 Thread 的类 QuestionLoader

问题情况:

当用户回答问题并按下 continue 按钮时,会触发函数 goToNextQuestion(),向用户显示下一个问题。下一个问题的预加载完成后可以立即显示,或者下一个问题仍在加载,我们必须等待。

问题:

现在,如果我们必须等待,我想显示一个Loading-Label和-Indicator。两者都在gui(置于界面构建器中)并且当时隐藏。我是这样做的:

func goToNextQuestion()
{
    //check if next question is already ready
    if (nextQuestionLoader.isFinished==false)
    {
        //not ready, so wait and show waiting indication
        labelLoading.isHidden = false
        loadingIndicator.startAnimating()
        while(nextQuestionLoader.isFinished == false) {}
        //question i now ready, hide waiting indication
        labelLoading.isHidden = true
        loadingIndicator.stopAnimating()
    }

    //so next question is ready and all good
}

我想要发生的是,当用户按继续并且下一个问题尚未准备就绪时, loadingIndicator labelLoading 在问题准备好之前显示。

现在发生的是 continue 被按下,没有任何显示,gui被阻止,如果问题已经准备就绪,那么它显示下一个问题,同样的事情发生在下面的问题中。

Screenshots of the area of my gui that is concerned for better visualitzation (对不起截图中获得的点数不同,与问题无关,只是2个不同的截图)

因此gui更新不会在问题完全加载之前发生,并且不会立即发生!

其他信息

  • 我尝试在代码的其他位置显示加载指示符并且它们正确显示,因此没有问题。
  • 当我在while循环之前和之后放置 print -command并跟随终端中的输出时,我看到在while循环之前和之后正确执行了print-commands。但是gui-update只会在事后发生
  • 函数 goToNextQuestion 在主线程中完全执行!

那么我怎样才能实现加载指示直接显示而显示后,while-loop等待另一个线程的完成?

我真的很绝望,因为我根本不知道如何解决这个问题。

我真的非常感谢你的帮助!

非常感谢你的时间!!

1 个答案:

答案 0 :(得分:0)

您的方法存在一些问题。

首先,您不应使用NSThread / Thread。系统类URLSession为您处理异步下载。 (创建线程既昂贵且容易出错。)请改用URLSession。你应该可以在网上找到很多例子,包括这里。

其次,你不能像你一样阻止主线程

    while(nextQuestionLoader.isFinished == false) {}

代码。由于您的下载在后台线程上运行,它将继续运行,但是通过阻止主线程,一切都会冻结,直到下载完成。在下载完成之前,您的UI更改无法在屏幕上绘制。

您应该使用委托方法或完成闭包来使用URLSession。它支持这两种方法。

我在Github上有一个名为Async_demo的项目,其中包含显示如何使用URLSession的工作代码。这是一个简化的例子,但它应该让你开始。