如何使用 pushViewController 方法防止计时器重置?

Posted

技术标签:

【中文标题】如何使用 pushViewController 方法防止计时器重置?【英文标题】:How to prevent timer reset using pushViewController method? 【发布时间】:2021-02-28 00:00:04 【问题描述】:

即使我切换视图控制器,我也会尝试保持计时器运行。我玩过单例架构,但我不太明白。推送一个新的视图控制器似乎更容易一些,但是当我调用下面的方法时,推送的视图控制器是空白的(看起来不像我在 Storyboards 中创建的视图控制器)。我尝试推送的计时器视图控制器也是第二个视图控制器,如果这有任何改变的话。

@objc func timerPressed() 
        let timerVC = TimerViewController()
        navigationController?.pushViewController(timerVC, animated: true)

【问题讨论】:

【参考方案1】:

您需要从情节提要中加载它

let vc = self.storyboard!.instantiateViewController(withIdentifier: "VCName") as! TimerViewController
self.navigationController?.pushViewController(timerVC, animated: true)

【讨论】:

【参考方案2】:

不确定您的问题是控制器为空白还是计时器重置。无论如何,如果您想将时间保留在内存中而不是在导航到其他地方时取消分配,我建议您这样做。

创建某种Constants 类,其中将有一个共享参数。

它可能看起来像这样:

class AppConstants 
    static let shared = AppConstants()
    var timer: Timer?

然后在此处通过共享参数访问计时器,执行您正在执行的任何操作。

AppConstants.shared.timer ...

【讨论】:

【参考方案3】:

您的问题有不同的部分。 Sh_Khan 告诉您加载视图控制器的方式有什么问题(仅调用视图控制器的 init 方法不会加载它的视图层次结构。通常您将在情节提要中定义视图控制器的视图,因此您需要从中实例化它故事板。)

然而,这并没有回答如何管理计时器的问题。如果您希望计时器是全局的而不是绑定到特定的视图控制器,那么单例是一个不错的选择。

发布您用于创建单例的代码,我们可以帮助您。

编辑:更新给 TimeManager 一个委托:

这个想法很简单。像这样的:

protocol TimeManagerDelegate 
    func timerDidFire()


class TimerManager 
    static let sharedTimerManager = TimerManager()
    weak var delegate: TimeManagerDelegate?

    //methods/vars to manage a shared timer.
    func handleTimer(timer: Timer) 
       //Put your housekeeping code to manage the timer here

       //Now tell our delegate (if any) that the timer has updated.
       //Note the "optional chaining" syntax with the `?`. That means that
       //If `delegate` == nil, it doesn't do anything.
       delegate?.timerDidFire() //Send a message to the delegate, if there is one.
    

然后在您的视图控制器中:

//Declare that the view controller conforms to the TimeManagerDelegate protocol
class SomeViewController: UIViewController, TimeManagerDelegate 

    //This is the function that gets called on the current delegate
    func timerDidFire() 
       //Update my clock label (or whatever I need to do in response to a timer update.)
    

    override func viewWillAppear() 
        super.viewWillAppear()
        //Since this view controller is appearing, make it the TimeManager's delegate.
        sharedTimerManager.delegate = self
    

【讨论】:

酷,我让它工作了!唯一的问题是,当我在视图控制器之间切换时,会显示我的时钟的默认标签,而不是当前滴答的时间。有什么办法吗? 你想要发生什么?你想让你的任何视图控制器显示当前时间吗?您的视图控制器堆栈中是否可以同时存在多个需要更新的视图控制器? 我想说给你的 TimerManager 单例一个弱委托属性和一个timerDidFire() 方法。在每个视图控制器的 viewWillAppear 方法中,执行sharedTimerManager.delegate = self。在 TimerManager 中,当定时器触发时,执行delegate?.timerDidFire()。在视图控制器中,遵守协议,并让您的 timerDidFire() 方法更新时钟标签。 查看我的答案的编辑。我描述了如何设置 TimeManager 以获取在计时器更新时收到通知的委托。 啊,好吧,我明白了问题所在。我想你误解了我的问题......对不起!让我试着澄清一下!因此,使用单例类,即使我切换视图控制器,我的计时器也会继续运行,但是,如果我切换视图控制器(重置为我输入的默认文本),我的时钟标签将重置。你知道如何解决这个问题吗?我不确定是否会使用代表,因为我不想只更新时钟的标签,但我想让它继续运行。

以上是关于如何使用 pushViewController 方法防止计时器重置?的主要内容,如果未能解决你的问题,请参考以下文章

如何解雇PushViewController?

如何在uitableviewcell swift上使用pushviewcontroller [重复]

pushViewController 后,如何禁用 backBarButtonItem?

如何使用 PushViewController 方法从 UIViewClass 导航到 UIViewController 类

如何使用 pushViewController 方法防止计时器重置?

如何覆盖 pushViewController 创建的导航栏的功能