Swift 3 - 调用准备 segue 时视图不更新

Posted

技术标签:

【中文标题】Swift 3 - 调用准备 segue 时视图不更新【英文标题】:Swift 3 - view doesn't update when prepare for segue is called 【发布时间】:2017-04-19 12:07:47 【问题描述】:

我有一个 unwind segue,它在将图像保存到磁盘时需要几秒钟才能完成。我想显示一个活动指示器,直到视图被关闭但视图没有更新。

这是我的函数,它在视图控制器被解除之前被调用:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == "saveRecord" 
        print("indicator")
        let indicator = UIActivityIndicatorView()
        indicator.frame = self.view.frame
        indicator.activityIndicatorViewStyle = .whiteLarge
        indicator.color = UIColor.blue
        indicator.hidesWhenStopped = true
        indicator.startAnimating()
        self.view.addSubview(indicator)
        self.view.layoutSubviews()
        print("laid out subviews")
    

两个打印语句执行,调试器显示指示器已作为子视图添加到主视图,但它没有出现在屏幕上。我错过了什么吗?

我知道指示器的位置没有问题,因为在 viewDidLoad 中运行相同的代码可以正确地将它显示在屏幕中间。

更新

我已经使用委托重新创建了 segue 函数,并且它正确保存了所有内容,但问题仍然存在。仍然没有活动指示器。

@IBAction func saveRecord(_ sender: Any) 
    print("indicator")
    let indicator = UIActivityIndicatorView()
    indicator.frame = self.view.frame
    indicator.activityIndicatorViewStyle = .whiteLarge
    indicator.color = UIColor.blue
    indicator.hidesWhenStopped = true
    indicator.startAnimating()
    self.view.addSubview(indicator)
    self.view.layoutSubviews()
    print("laid out subviews")
    saveImages()
    print("saved images")
    self.delegate?.saveRecord(name: name!, category: category)
    print("saved record")
    self.navigationController?.popViewController(animated: true)

更新 2

我现在真的很困惑!这将启动指标:

@IBAction func saveRecord(_ sender: Any) 
    print("indicator")
    indicator.startAnimating()
    //saveImages()
    //print("images saved")
    //performSegue(withIdentifier: "saveRecord", sender: self)

但这不是:

@IBAction func saveRecord(_ sender: Any) 
    print("indicator")
    indicator.startAnimating()
    saveImages()
    print("images saved")
    performSegue(withIdentifier: "saveRecord", sender: self)

【问题讨论】:

您是否在代码中的某个位置调用了performSegue 谢谢艾哈迈德。是的,我尝试了各种触发 segue 的方法,但仍然遇到同样的问题。 【参考方案1】:

问题是 UI 在 saveRecord 函数完成之前不会更新,但随后会调用 segue,因此视图控制器会立即关闭。我使用调度队列解决了这个问题——我今天学到的另一个新技能!:

@IBAction func saveRecord(_ sender: Any) 
    indicator.startAnimating()
    DispatchQueue.global(qos: .userInitiated).async 
        self.saveImages()
        DispatchQueue.main.async 
            self.performSegue(withIdentifier: "saveRecord", sender: self)
        
    

【讨论】:

【参考方案2】:

我认为你应该使用 popViewController 而不是 unwind segue。然后,您可以使用后退按钮上的自定义功能进行更多控制。

那么你可以做的是:

当您单击返回按钮(或保存图像按钮)时,添加您的指示器 然后保存图片 保存图像时移除指示符 弹出视图控制器

【讨论】:

谢谢。我仍然需要在目标视图控制器中做事,所以我认为这不适合我。 然后使用委托模式。而且,Paulw11 的答案与我建议的几乎相同;) 再次感谢。在代表模式的速成课程(我以前没有使用过)之后,我重新设计了它,但我仍然遇到同样的问题 - 请参阅更新后的问题。 显示保存图像功能。问题是,当您确定您的图像已保存时,您需要弹出视图控制器。您现在要做的是:开始保存图像并立即弹出控制器。这意味着,您无需等待图像被保存。我知道您的图像已保存,但这可能发生在后台任务中,因此您需要确定任务已完成。你如何保存图像?到服务器?核心数据? 保存图像功能从 UIImagePickerController 获取图像并保存三个不同的版本(高分辨率、中分辨率和低分辨率)。只有在完成后才会调用 pop。问题是 UI 直到保存图像和弹出完成后才更新。【参考方案3】:

您无法在prepare(for:) 中更新您的观点;转场已经在进行中。

与其直接从 UI 元素触发展开转场,不如触发一个显示活动指示器并执行保存的操作方法,然后调用 performSegue(withIdentifier:"yourUnwindSegueIdentifier", sender:self) 来实际执行展开。

【讨论】:

谢谢,我知道你来自哪里,但是如果没有展开转场,我如何在目标视图控制器中完成转场操作?我对此感到困惑,因为文档 developer.apple.com/library/content/featuredarticles/… 说“您还可以使用展开操作在展开序列完成之前更新当前视图控制器。” 你仍然会有一个放松的转场;按住 Ctrl 键从视图控制器图标拖动到退出图标,选择 unwind 方法并为生成的 segue 提供一个标识符,以便您可以调用 performSegue 谢谢保罗。同样,我可以使用该方法使所有保存代码正常工作,但我的指示器仍然不显示。 saveImages 是做什么的? saveImages 从 UIImagePickerController 获取图像,创建三个版本(高、中、低分辨率)并将它们写入文档目录。

以上是关于Swift 3 - 调用准备 segue 时视图不更新的主要内容,如果未能解决你的问题,请参考以下文章

不能在代码中调用 segue (Swift)

准备 segue 数组时不包含数据(使用 swift)

使用 Sender 为 Swift 中的 Segue 做准备

Swift segue 到函数中的另一个视图控制器

在 Xcode 8 和 Swift 3.0 中删除覆盖后准备 segue 崩溃

不使用 Storyboard segues 的自定义视图转换 (Swift)