SwiftUI Timer仿短信发送倒计时(教程含源码)

实战需求

SwiftUI Timer仿短信发送倒计时

本文价值与收获

看完本文后,您将能够作出下面的界面

截屏2020-08-03 上午11.12.23.png

看完本文您将掌握的技能

  • 掌握timer基础使用
  • 实现三个业务逻辑的切换
  • 实现倒计时

基础知识

Timer

经过一定时间间隔后将触发的计时器,将指定的消息发送到目标对象。

class Timer : NSObject

总览

计时器与运行循环配合使用。运行循环会维护对其计时器的强引用,因此在将计时器添加到运行循环后,您不必维护自己的对计时器的强引用。

为了有效地使用计时器,您应该了解运行循环的运行方式.计时器不是实时机制。如果在长时间运行的循环调用期间或运行循环处于不监视计时器的模式时发生计时器的触发时间,则直到下一次运行循环检查计时器时,计时器才会启动。因此,计时器触发的实际时间可能要晚得多。另请参阅计时器容差。

比较重复和不重复计时器

您可以指定计时器在创建时是重复还是不重复。非重复计时器触发一次,然后自动使其自身无效,从而防止计时器再次触发。相比之下,重复计时器会触发,然后在同一运行循环上重新安排自身的时间。重复计时器始终根据计划的点火时间进行调度,而不是实际的点火时间。例如,如果定时器计划在特定时间触发,然后每5秒触发一次,则即使实际触发时间被延迟,计划的触发时间也将始终落在原始的5秒时间间隔上。如果触发时间延迟得太远,以至于超过了计划的触发时间中的一个或多个,则计时器在该时间段仅触发一次;触发后,计时器会重新安排,

计时器公差

在iOS 7和更高版本以及macOS 10.9和更高版本中,您可以指定计时器的公差(tolerance)。计时器启动时的这种灵活性提高了系统优化的能力,以提高节电和响应速度。计时器可以在其预定的点火日期与预定的点火日期加公差之间的任何时间点火。计时器不会在计划的触发日期之前触发。对于重复计时器,下一个点火日期是根据原始点火日期计算的,而不考虑各个点火时间的公差,以避免漂移。默认值为零,这意味着不应用其他公差。系统保留对某些计时器应用少量容差的权利,而不论该tolerance属性的值如何。

作为计时器的用户,您可以确定计时器的适当公差。一般规则,对于重复计时器,将公差设置为间隔的至少10%。即使很小的容差也会对应用程序的电源使用产生重大的积极影响。系统可以强制执行公差的最大值。

在运行循环中安排计时器

您可以一次仅在一个运行循环中注册一个计时器,尽管可以将其添加到该运行循环中的多个运行循环模式中。有三种创建计时器的方法:

  • 使用或类方法创建计时器,并在默认模式下将其安排在当前运行循环上。scheduledTimer(timeInterval:invocation:repeats:)scheduledTimer(timeInterval:target:selector:userInfo:repeats:)

  • 使用或类方法创建计时器对象,而不在运行循环上安排它。(创建计时器后,必须通过调用相应对象的方法将计时器手动添加到运行循环中。)init(timeInterval:invocation:repeats:)init(timeInterval:target:selector:userInfo:repeats:)add(_:forMode:)RunLoop

  • 分配计时器并使用方法将其初始化。(创建计时器后,必须通过调用相应对象的方法将计时器手动添加到运行循环中。)init(fireAt:interval:target:selector:userInfo:repeats:)add(_:forMode:)RunLoop

一旦安排在运行循环中,计时器就会以指定的时间间隔触发,直到失效为止。非重复计时器在触发后立即失效。但是,对于重复计时器,您必须通过调用其invalidate()方法自己使计时器对象无效。调用此方法要求从当前运行循环中删除计时器。因此,您应该始终invalidate()从安装计时器的同一线程中调用该方法。使计时器无效会使它立即禁用,以使其不再影响运行循环。然后,运行循环将删除该计时器(以及该计时器必须具有的强引用),方法是在invalidate()方法返回之前或稍后。一旦失效,计时器对象将无法重用。

重复触发计时器后,它将在指定的内,为最近的将来日期安排下一次触发,该日期是最近一次计划的点火日期之后计时器间隔的整数倍tolerance。如果调出执行选择器或调用所需的时间长于指定的间隔,则计时器仅安排下一次触发;否则,定时器将仅计划下一次触发。也就是说,计时器不会尝试补偿在调用指定的选择器或调用时可能发生的任何丢失的触发。

子类注释

不要子类化Timer。


主题

创建一个计时器

1、class func scheduledTimer(withTimeInterval: TimeInterval, repeats: Bool, block: (Timer) -> Void) -> Timer

创建一个计时器,并在默认模式下将其安排在当前运行循环上。

2、class func scheduledTimer(timeInterval: TimeInterval, target: Any, selector: Selector, userInfo: Any?, repeats: Bool) -> Timer

创建一个计时器,并在默认模式下将其安排在当前运行循环上。

3、class func scheduledTimer(timeInterval: TimeInterval, invocation: NSInvocation, repeats: Bool) -> Timer

创建一个新计时器,并在默认模式下将其安排在当前运行循环上。

4、init(timeInterval: TimeInterval, repeats: Bool, block: (Timer) -> Void)

使用指定的时间间隔和块初始化计时器对象。

5、init(timeInterval: TimeInterval, target: Any, selector: Selector, userInfo: Any?, repeats: Bool)

使用指定的对象和选择器初始化计时器对象。

6、init(timeInterval: TimeInterval, invocation: NSInvocation, repeats: Bool)

使用指定的调用对象初始化计时器对象。

7、init(fire: Date, interval: TimeInterval, repeats: Bool, block: (Timer) -> Void)

使用指定的块为指定的日期和时间间隔初始化计时器。

8、init(fireAt: Date, interval: TimeInterval, target: Any, selector: Selector, userInfo: Any?, repeats: Bool)

使用指定的对象和选择器初始化计时器。


触发计时器

func fire()

使计时器的消息发送到其目标。


停止计时器

func invalidate()

停止计时器再次触发,并请求将其从运行循环中删除。


检索计时器信息

1、var isValid: Bool

一个布尔值,指示计时器当前是否有效。

2、var fireDate: Date

计时器将触发的日期。

3、var timeInterval: TimeInterval

计时器的时间间隔,以秒为单位。

4、var userInfo: Any?

接收者的对象。userInfo


配置射击公差

1、var tolerance: TimeInterval

在计划的触发日期之后定时器可以触发的时间。


作为组合发布者触发消息

1、static func publish(every: TimeInterval, tolerance: TimeInterval?, on: RunLoop, in: RunLoop.Mode, options: RunLoop.SchedulerOptions?) -> Timer.TimerPublisher

返回一个发布者,该发布者在给定的时间间隔内反复发出当前日期。

2、class Timer.TimerPublisher

在给定的时间间隔内反复发出当前日期的发布者。


代码

还有 21% 的精彩内容
©著作权归作者所有,转载或内容合作请联系作者
支付 ¥9.90 继续阅读
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341