我有一个UIPickerView,一旦选择了特定的行,就会触发实现大量的计算。如果用户等待计算完成,显示计算结果的UILabel(txtRunwayDest)会在大约5秒钟内成功刷新(计算正在进行时)。为了保护应用程序免受用户在进行计算时继续旋转UIPicker(这可能导致显着滞后),我决定在选择行时显示带有旋转活动指示器的弹出视图。我把计算放在后台线程上。
@IBOutlet weak var txtRunwayDest: UILabel!
let pckRunwayDest = UIPickerView()
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
if (pickerView == self.pckRunwayDest)
{
print("CHECK 0")
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
alert.view.tintColor = UIColor.black()
let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50)) as UIActivityIndicatorView
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
DispatchQueue.global(attributes: .qosBackground).async {
... // CODE
if (row == 0)
{
... // CODE
}
else
{
... // CODE
}
DispatchQueue.main.sync {
print("CHECK DISPLAY")
// Refresh all values on screen
self.displayValues()
// Dismiss the popup view
self.dismiss(animated: false, completion: nil)
}
}
}
}
func displayValues()
{
if (someValue == nil)
{
self.txtRunwayDest.text = "Not selected";
}
else
{
print("START SHOWING TEXT")
self.txtRunwayDest.text = appSingleton.runwayDestShared!.0 + " (" + appSingleton.runwayDestShared!.2 + ")"
print("END SHOWING TEXT")
}
}
所以,一切正常,只是在完成所有计算并且UIView被解除后,txtRunwayDest文本出现在屏幕上大约5-10秒。主线程启动后,控制台立即显示“END SHOWING TEXT”,但正如我所说,标签只有在显着滞后后才会改变。
有什么想法吗?谢谢!
答案 0 :(得分:0)
通过解决应该在后台线程中放入什么代码以及主线程中的哪个代码来管理来解决问题。从长远来看,我把所有东西放在DispatchQueue.main.sync中,一切都按预期工作。感谢Leo Dabus提供了宝贵的建议。