Ios 如何在用户使用swift单击表视图中的一个单元格时立即运行计时器?

Ios 如何在用户使用swift单击表视图中的一个单元格时立即运行计时器?,ios,swift,uitableview,timer,Ios,Swift,Uitableview,Timer,我的UI中有两个视图控制器,我的目标是,只要用户单击表视图中的一个单元格,就会出现一个带有计时器的弹出窗口(另一个视图控制器) 但是,当我构建应用程序并单击其中一个单元格时,标签上仍然显示label,并且不会倒计时 我还收到一个错误,在同一行中,Unicode卷曲引号被替换为“”,并且在整型文字前缀后应该是数字(我指出了它在下面的那一行) 此类用于具有表视图的视图控制器 public func tableView(_ tableView: UITableView, numberOfRowsIn

我的UI中有两个视图控制器,我的目标是,只要用户单击表视图中的一个单元格,就会出现一个带有计时器的弹出窗口(另一个视图控制器)

但是,当我构建应用程序并单击其中一个单元格时,标签上仍然显示label,并且不会倒计时

我还收到一个错误,在同一行中,Unicode卷曲引号被替换为“”,并且在整型文字前缀后应该是数字(我指出了它在下面的那一行)

此类用于具有表视图的视图控制器

 public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return(redeem.count)
    }


    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {

//bringing down the array to print

        let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
        cell.textLabel?.text = redeem[indexPath.row]

        return(cell)
    }


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {


        let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbPopUpID") as! PopUpViewController

        self.addChildViewController(popOverVC)
        popOverVC.view.frame = self.view.frame
        self.view.addSubview(popOverVC.view)
        popOverVC.didMove(toParentViewController: self)


    }   
此类用于PopUpViewController

import UIKit

class PopUpViewController: UIViewController
{

    @IBOutlet weak var timerLabel: UILabel!

    @IBAction func closePopUp(_ sender: Any)
    {
         self.view.removeFromSuperview()
     }

     var seconds = 60
     var timer = Timer()
     var isTimeRunning = false

     override func viewDidLoad()
     {
         super.viewDidLoad()


         self.view.backgroundColor = UIColor.black.withAlphaComponent(0.8)


     }

     func runTimer()
     {
         timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(PopUpViewController.updateTimer)), userInfo: nil, repeats: true)
     }

     func timeString(time:TimeInterval) -> String
     {
         let hours = Int(time) / 3600
         let minutes = Int(time) / 60 % 60
         let seconds = Int(time) % 60
//getting the error message for the line below
         return String(format:”%02i:%02i:%02i”, hours, minutes, seconds)
     }

     func updateTimer()
     {
         if seconds < 1
         {
             self.view.removeFromSuperview()
         }
         else
         {
             seconds -= 1
//getting an error message here saying EXC_BAD_INSTRUCTION (unexpectedly found nil while unwrapping an Optional value)
             timerLabel.text = timeString(time: TimeInterval(seconds))
         }

     }
导入UIKit
类PopUpViewController:UIViewController
{
@IBVAR时间标签:UILabel!
@iAction func关闭弹出窗口(\发送方:任何)
{
self.view.removeFromSuperview()
}
var秒=60
var timer=timer()
var isTimeRunning=false
重写func viewDidLoad()
{
super.viewDidLoad()
self.view.backgroundColor=UIColor.black.withAlphaComponent(0.8)
}
func运行计时器()
{
timer=timer.scheduledTimer(时间间隔:1,目标:self,选择器:(#选择器(PopUpViewController.updateTimer)),userInfo:nil,repeats:true)
}
func timeString(时间:TimeInterval)->String
{
让小时数=整数(时间)/3600
分钟数=整数(时间)/60%60
设秒=整数(时间)%60
//正在获取以下行的错误消息
返回字符串(格式:“%02i:%02i:%02i”,小时、分钟、秒)
}
func updateTimer()
{
如果秒数小于1
{
self.view.removeFromSuperview()
}
其他的
{
秒-=1
//在此处获取错误消息,表示EXC_BAD_指令(在展开可选值时意外发现nil)
timerLabel.text=timeString(时间:时间间隔(秒))
}
}
  • 我看不到对
    运行计时器的任何调用。因此计时器永远不会启动。我建议使用
    viewwillbeen
    viewdidebeen
    。将此添加到PopupViewController:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        runTimer()
    }
    
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
        {
            let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbPopUpID") as! PopUpViewController
    
            self.present(popOverVC, animated: true, completion: nil)
        }
    
  • 您只需调用
    self.view.removeFromSuperview()
    关闭弹出窗口,这将从视图层次结构中删除视图,但viewController仍注册为子viewController。我建议使用
    presentViewController
    显示弹出窗口,并使用
    dismissViewControllerAnimated
    将其删除

  • 显示视图控制器:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        runTimer()
    }
    
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
        {
            let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "sbPopUpID") as! PopUpViewController
    
            self.present(popOverVC, animated: true, completion: nil)
        }
    
    以下列方式驳回:

        @IBAction func closePopUp(_ sender: Any)
        {
            self.dismiss(animated: true, completion: nil)
        }
    
  • 您使用了错误的引号(“代替”),因此出现了错误

  • 所需的基本代码。请记住,无论何时创建新计时器,都需要确保对现有计时器调用invalidate(),否则可能会在不希望的地方生成多个计时器

    class myClass: UIViewController {
        //...
        var timer:Timer!
        //...
        func createTimer(interval: TimeInterval, selector: Selector) {
            if timer == nil {
                timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: selector , userInfo: nil, repeats: true)
            }
        }
        //...
        func cancelTimer() {
            timer.invalidate()
            timer = nil
        }
        //...
        override func viewWillDisappear(_ animated: Bool) {
            cancelTimer()
        }
    }
    

    谢谢,第3点确实解决了这个问题。现在,对于第1点和第2点,我没有像我希望的那样完全遵循。我确实看到,现在我没有调用函数runTimer,我将如何使用viewdidappease调用它?对于第2点,我如何在没有错误的情况下更改它?我键入了runTimer()在viewDidLoad函数中,现在是崩溃谢谢你,这确实帮了我很大的忙。我在最后一行代码中收到了一条额外的错误消息,并在上面评论了它现在所说的内容。您似乎失去了与timerLabel的出口连接。无论何时使用计时器,不要忘记使用Timer.invalidate();Timer=nil。