【问题标题】:Timer countdown in swift skipping seconds and pausing快速跳过秒和暂停的计时器倒计时
【发布时间】:2015-09-18 19:11:15
【问题描述】:

我正在为我正在更新的应用程序制作倒计时组件。我终于让它工作了,但是当它在我的模拟器上或者当我通过手机运行它时,它会卡住并跳过几秒钟,有时会冻结我的屏幕并且不允许我更改视图等。这是我下面的代码。我很好奇为什么会这样。

提前谢谢你!

class CountdownViewController: UIViewController {

@IBOutlet weak var days: UILabel!
@IBOutlet weak var hours: UILabel!
@IBOutlet weak var minutes: UILabel!
@IBOutlet weak var seconds: UILabel!

var timer:NSTimer!

func reloadData(){
    self.viewDidLoad()
}

override func viewDidLoad() {
    super.viewDidLoad()

    self.timer = NSTimer(timeInterval: 0.5, target: self, selector: Selector("reloadData"), userInfo: nil, repeats: true)

    NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSRunLoopCommonModes)

    self.canDisplayBannerAds = true

    // here we set the current date
    let date = NSDate()
    let calendar = NSCalendar.currentCalendar()
    let components = calendar.components(.CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitMonth | .CalendarUnitYear | .CalendarUnitDay | .CalendarUnitSecond, fromDate: date)
    let hour = components.hour
    let minute = components.minute
    let month = components.month
    let year = components.year
    let day = components.day
    let second = components.second

    let currentDate = calendar.dateFromComponents(components)

    // here we set the due date. When the timer is supposed to finish

    let userCalendar = NSCalendar.currentCalendar()

    let electionDate = NSDateComponents()
    electionDate.year = 2016
    electionDate.month = 11
    electionDate.day = 08
    electionDate.hour = 00
    electionDate.minute = 00
    electionDate.second = 00
    let electionDay = userCalendar.dateFromComponents(electionDate)!


    // Here we compare the two dates
    electionDay.timeIntervalSinceDate(currentDate!)

    let dayCalendarUnit: NSCalendarUnit = (.CalendarUnitDay | .CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond)

    //here we change the seconds to hours,minutes and days
    let electionDayDifference = userCalendar.components(dayCalendarUnit, fromDate: currentDate!, toDate: electionDay,options: nil)

    //finally, here we set the variable to our remaining time
    var daysLeft = electionDayDifference.day
    var hoursLeft = electionDayDifference.hour
    var minutesLeft = electionDayDifference.minute
    var secondsLeft = electionDayDifference.second

    days.text = String(daysLeft)
    hours.text = String(hoursLeft)
    minutes.text = String(minutesLeft)
    seconds.text = String(secondsLeft)

}

【问题讨论】:

  • 我将 timeInterval 设置为 1.0 并尝试 0.5 看看是否有帮助,真的没有区别。另外,我不知道这是否与它有关,但我正在Mac Mini上开发,所以不知道这是否会影响它。
  • 为什么叫viewDidLoad?那调用 super.viewDidLoad 等等。在函数中取出。
  • 另外,为什么不使用 NSTimer.scheduledTimerWithTimeInterval 呢?
  • 我取出 self.timer = NSTimer(timeInterval: 0.5, target: self, selector: Selector("reloadData"), userInfo: nil, repeats: true) NSRunLoop.currentRunLoop().addTimer( self.timer, forMode: NSRunLoopCommonModes) 并将其替换为有效的 scheduleTimerWithTimeInteval。还是有点冷。我真的不明白你对 viewDidLoad 的意思。我该怎么办? @雅罗斯拉夫
  • 我对 NSRunLoop 不熟悉。另外,我使用这种格式:“选择器:”reloadData“”。但回到你的问题,我真的不会打电话给 viewDidLoad。

标签: ios swift nstimer


【解决方案1】:

您每 0.5 秒向 RunLoop 添加越来越多的计时器。而且它们都被同时触发,随着时间的推移导致性能下降。您需要将// here we set the current date 注释下方的所有代码移动到reloadData 函数并从那里删除self.viewDidLoad(),一切都应该没问题。您的计时器将只安排一次,并且每 0.5 秒重复调用一次reloadData(因为您使用repeats: true 参数创建了它)。

【讨论】:

  • 我希望它每秒改变一次,你建议每 1.0 或 0.5 调用一次,还是没关系? @glyuck
【解决方案2】:

不要调用 viewDidLoad()

它是一种委托方法,由视图控制器调用(一次),指定用于设置一次。

将要在计时器触发后执行的代码放入自定义函数中。 无需反复创建定时器,将参数repeats设置为true会定期调用选择器。

【讨论】:

  • 只是 viewDidLoad 不是一个委托,而是一个 UIViewController 方法,但你是对的!
  • 它不是委托(任何类型的),它只是UIViewController 类的一个方法,用户不会调用。
  • 是的,我知道,但行为与类本身调用的委托方法相同
猜你喜欢
  • 1970-01-01
  • 2016-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-27
  • 1970-01-01
  • 2019-08-18
  • 1970-01-01
相关资源
最近更新 更多