iOS任何界面全屏炫酷倒计时,一句代码就够了
概述
详细
一、准备工作
1、需要Xcode8开发环境
2、本例支持iOS8+
3、本例实现的功能:一句代码在任何界面实现一个全屏倒计时
二、如何使用
这是我的工程结构,把箭头指向的文件夹拖入你的工程

然后需在你的工程中用到的地方倒入头文件#import "WZBCountdownButton.h",在需要开始倒计时的地方使用[WZBCountdownButton play]然后按command + R运行即可!
代码如下:

效果如下:

因为+play方法默认执行倒计时3秒,如果想定制倒计时时间,请使用[WZBCountdownLabel playWithNumber:5];效果如下:

有的需求可能是这样:在倒计时结束后我想实现一句话,请使用[WZBCountdownLabel playWithNumber:5 endTitle:@"GO!"];
效果如下:

此外,我在代码里增加了对当前倒计时状态的监听,提供两种方式,block和代理。方法一是你可以通过实现一下两个block来监听倒计时状态:
/** 倒计时完成时调的block */
typedef void(^CountdownSuccessBlock)(WZBCountDownButton *button);
/** 倒计时开始时调的block */
typedef void(^CountdownBeginBlock)(WZBCountDownButton *button);
或者通过[WZBCountdownButton addDelegate:self]; 添加代理,然后实现一下两个代理方法
/** 倒计时完成时调用 */
- (void)countdownSuccess:(WZBCountDownButton *)button
{
NSLog(@"倒计时完成");
} /** 倒计时开始时调用 */
- (void)countdownBegin:(WZBCountDownButton *)button
{
NSLog(@"倒计时开始");
}
除此之外,我还定义了方法,可以倒计时图片,就是把一堆图片,一秒一个的播放,如下:
[WZBCountDownButton playWithImages:imageNames begin:^(WZBCountDownButton *button) {
NSLog(@"倒计时开始");
} success:^(WZBCountDownButton *button) {
NSLog(@"倒计时结束");
}];
效果如下:

三、实现思路
以下是几个开始倒计时的方法:
#pragma mark - play methods
+ (instancetype)play {
return [self playWithNumber:0];
} + (instancetype)playWithNumber:(NSInteger)number {
return [self playWithNumber:number endTitle:[WZBCountDownButton share].endTitle];
} + (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle {
return [self playWithNumber:number endTitle:endTitle success:[WZBCountDownButton share].countdownSuccessBlock];
} + (instancetype)playWithNumber:(NSInteger)number success:(CountdownSuccessBlock)success {
return [self playWithNumber:number endTitle:[WZBCountDownButton share].endTitle success:success];
} + (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle success:(CountdownSuccessBlock)success{
return [self playWithNumber:number endTitle:endTitle begin:[WZBCountDownButton share].countdownBeginBlock success:success];
}
上面这几个方法最终都会走到下边这个方法,核心代码:
+ (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle begin:(CountdownBeginBlock)begin success:(CountdownSuccessBlock)success {
// isAnimationing 用来判断目前是否在动画
if (isAnimationing) return nil;
WZBCountDownButton *button = [WZBCountDownButton share];
[button setImage:[UIImage new] forState:UIControlStateNormal];
button.countDownType = WZBCountDownNumber;
button.hidden = NO;
// 给全局属性赋值
// 默认三秒
button.number = 3;
if (number && number > 0) button.number = number;
if (endTitle) button.endTitle = endTitle;
if (success) button.countdownSuccessBlock = success;
if (begin) button.countdownBeginBlock = begin;
[self setupButtonBase:button];
// 动画倒计时部分
[self scaleActionWithBeginBlock:begin andSuccessBlock:success button:button];
return button;
}
// 动画倒计时部分
+ (void)scaleActionWithBeginBlock:(CountdownBeginBlock)begin andSuccessBlock:(CountdownSuccessBlock)success button:(WZBCountDownButton *)button {
if (!isAnimationing) { // 如果不在动画, 才走开始的代理和block
if (begin) begin(button);
if ([button.delegate respondsToSelector:@selector(countdownBegin:)]) [button.delegate countdownBegin:button];
}
if (button.countDownType == WZBCountDownImage) {
[self setAnimationImage:button];
} else {
[self setAnimationNumber:button];
}
}
// 播放倒计时图片
+ (void)setAnimationImage:(WZBCountDownButton *)button {
if (button.images.count > 0) {
isAnimationing = YES;
[button setImage:[UIImage imageNamed:button.images.firstObject] forState:UIControlStateNormal];
[UIView animateWithDuration:1.0f animations:^{
button.transform = CGAffineTransformIdentity;
button.alpha = 1;
} completion:^(BOOL finished) {
if (finished) {
button.alpha = 0;
button.transform = CGAffineTransformMakeScale(5, 5);
if (button.images.count > 0) {
[button.images removeObjectAtIndex:0];
[self scaleActionWithBeginBlock:button.countdownBeginBlock andSuccessBlock:button.countdownSuccessBlock button:button];
}
}
}];
} else {
// 调用倒计时完成的代理和block
if ([button.delegate respondsToSelector:@selector(countdownSuccess:)]) [button.delegate countdownSuccess:button];
if (button.countdownSuccessBlock) button.countdownSuccessBlock(button);
[self hidden];
}
}
简单解释下代码的实现原理:
调用这个方法,首先先判断当前是否正在播放倒计时,如果正在播放,直接return nil;
如果没有在播放,则创建一个UIButton,然后为button赋值(一些全局变量),如果是数字倒计时,那么为button赋值为初始的数字,然后再判断有没有结束语,如果有,则总倒计时增加一秒钟(为最后的结束语留一秒播放时间)。然后判断总数值是否大于0,如果不大于,则证明已经播放完了,然后调用代理和block,以及隐藏掉self。如果判断大于0,则开始开始循环播放动画,这里用的是UIView动画,每次动画执行1秒,动画执行结束,控制全局数值的number属性减一,重新开始循环上边步骤。
如果是倒计时图片,则开始走播放倒计时图片的方法,先判断外部传入的图片数组个数是否大于0,如果不大于,则证明已经倒计时结束了(或者使用者没有传入任何图片),然后调用代理和block,以及隐藏self。如果图片个数大于0,从图片数组中取出第一个图片为button赋值,然后开始动画,动画执行完,先把数组中的第一张图片移除掉,然后重新开始上边的步骤。知道执行结束为止。
此demo中其他可用的方法:
/**
设置文字颜色和字体大小 @param textColor 文字颜色(默认红色)
@param textFont 字体大小(默认为20)
*/
+ (void)setTextColor:(UIColor *)textColor textFont:(UIFont *)textFont; /**
设置文字颜色 @param textColor 文字颜色(默认红色)
*/
+ (void)setTextColor:(UIColor *)textColor; /**
设置字体大小 @param textFont 字体大小(默认为20)
*/
+ (void)setTextFont:(UIFont *)textFont; /**
全是默认值的play方法
*/
+ (instancetype)play; /**
隐藏
*/
+ (void)hidden; /**
初始化并开始播放 @param number 倒计时开始数字
@return WZBCountDownButton的实例
*/
+ (instancetype)playWithNumber:(NSInteger)number; /**
初始化并开始播放 @param number 倒计时开始数字
@param endTitle 倒计时结束时显示的字符
@return WZBCountDownButton的实例
*/
+ (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle; /**
初始化并开始播放 @param number 倒计时开始数字
@param success 倒计时开始回调
@return WZBCountDownButton的实例
*/
+ (instancetype)playWithNumber:(NSInteger)number success:(CountdownSuccessBlock)success; /**
初始化并开始播放 @param number 倒计时开始数字
@param endTitle 倒计时结束时显示的字符
@param success 倒计时开始回调
@return WZBCountDownButton的实例
*/
+ (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle success:(CountdownSuccessBlock)success; /**
初始化并开始播放 @param number 倒计时开始数字
@param endTitle 倒计时结束时显示的字符
@param begin 倒计时开始回调
@param success 倒计时完成回调
@return WZBCountDownButton的实例
*/
+ (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle begin:(CountdownBeginBlock)begin success:(CountdownSuccessBlock)success; /**
初始化并开始播放 @param images 需要播放的图片
@param begin 倒计时开始回调
@param success 倒计时完成回调
@return WZBCountDownButton的实例
*/
+ (instancetype)playWithImages:(NSArray *)images begin:(CountdownBeginBlock)begin success:(CountdownSuccessBlock)success; /**
初始化并开始播放 @param images 需要播放的图片
@param duration 时间间隔(暂未实现)
@param begin 倒计时开始回调
@param success 倒计时完成回调
@return WZBCountDownButton的实例
*/
+ (instancetype)playWithImages:(NSArray *)images duration:(NSTimeInterval)duration begin:(CountdownBeginBlock)begin success:(CountdownSuccessBlock)success; /**
绑定代理
*/
+ (void)addDelegate:(id<WZBCountDownButtonDelegate>)delegate; /**
倒计时完成时的block监听
*/
+ (void)addCountdownSuccessBlock:(CountdownSuccessBlock)success; /**
倒计时开始时的block监听
*/
+ (void)addCountdownBeginBlock:(CountdownBeginBlock)begin; /**
倒计时开始时和结束时的block监听
*/
+ (void)addCountdownBeginBlock:(CountdownBeginBlock)begin successBlock:(CountdownSuccessBlock)success;
这些方法的注视都比较清楚,就不再过多解释了。具体请下载demo。
四、其他
以上介绍了基本的使用方法,在文件WZBCountDownButton.h中还有一些其他的一些操作,比如定制文字颜色、文字大小这些,比较简单,就不过多赘述了。我这个demo的功能很简单,但是封装的特别好,没有一个实例方法,全是直接拿类名可以直接调用的类方法,很值得学习一下。
注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
iOS任何界面全屏炫酷倒计时,一句代码就够了的更多相关文章
- 炫酷:一句代码实现标题栏、导航栏滑动隐藏。ByeBurger库的使用和实现
本文已授权微信公众号:鸿洋(hongyangAndroid)原创首发. 其实上周五的时候已经发过一篇文章.基本实现了底部导航栏隐藏的效果.但是使用起来可能不是很实用.因为之前我实现的方式是继承了系统的 ...
- WPF解决界面全屏化但不遮挡任务栏的问题
原文:WPF解决界面全屏化但不遮挡任务栏的问题 学习C#有一段时间了,现在跟着做项目,碰到有个客户端界面总是全屏,对于客户来说没有任务栏很不习惯,所以做了些略微的修改 </pre>&l ...
- 用javascript写Android和iOS naitve应用,实在炫酷。
关注NativeScript有一段时间了,说好了的三月发第一个Beta版,终于发布了. // declare the extended NativeScriptActivity functionali ...
- ios滑动手势全屏(这段代码实现了下一级控制器滑到上一级控制器)
在自定义导航控制器里面加以下代码就增加全屏滑动手势 >推向前一个控制器 // HBNavigationController.m // #import "HBNavigationCon ...
- JS 取消iOS播放自动全屏:
iOS下浏览器模式下h5播放器强制是全屏的,除非在app下才可以非全屏播放,需要两个配置: (1)播放器添加参数: playsinline:true(我使用的是阿里云的播放器,其他的需要自己找找是那个 ...
- iOS - 视频播放处理全屏/横屏时候遇见的坑
视频播放想要全屏,使用shouldAutorotate方法禁止主界面,tabbar控制器横屏,导致push进入播放页面不能横屏的问题... - (BOOL)shouldAutorotate { ret ...
- HTML5新标签video在iOS上默认全屏播放
今天做一个app时发现一个问题,应用html5中的video标签加载视频,在Android手机上默认播放大小,但是换成iPhone手机上出问题了,默认弹出全屏播放,查找了好多论坛,都没有谈论这个的.然 ...
- html-----vedio标签(HTML5新标签VIDEO在IOS上默认全屏播放)
今天做一个app时发现一个问题,应用html5中的video标签加载视频,在Android手机上默认播放大小,但是换成iPhone手机上出问题了,默认弹出全屏播放,查找了好多论坛,都没有谈论这个的.然 ...
- 炫酷实用的CSS3代码垂直手风琴菜单
今天在微博上看到别人分享的代码,自己拿来自己保存着. 代码效果如下: 下面是源码: index.html <!DOCTYPE html> <html > <head> ...
随机推荐
- SQL Server批量替换全部表中内容sql语句-清楚挂马
有朋友常常会发现自己的数据库全部的内容给插入了一些代码,假设要一个个表一个个记录去删除.太麻烦了,以下我在在网上找到一个能够批量删除的方法,实际上是批量把那段恶意代码替换,很高速. declare @ ...
- iOS抽屉效果
源代码下载 抽屉效果第三方类库下载 所需第三方类库下载 側拉栏抽屉效果图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTUhUaW9z/font/5a6L ...
- 1、cocos2d-x环境安装
1 所需软件 2 安装python-2.7.8.amd64.msi 注意将当中的有一步设置,Add python.exe to path 设置python的环境变量 3 解压cocos2d-x- ...
- 用java解析在OpenStreetMap上下载的地图数据(SAX版,适合比较大的xml文件)
java程序如下: package gao.map.preprocess; import java.io.BufferedWriter; import java.io.File; import jav ...
- Informatica 常用组件Lookup之六 查询
PowerCenter 基于您在查找转换中配置的端口和属性来查询查找.当第一行输入到查找转换时,PowerCenter 运行一个默认的 SQL 语句.如果使用关系查找,您可以在"查找 SQL ...
- 通过小实例谈谈javascript的间隔调用和延时调用
用 setInterval方法可以以指定的间隔实现循环调用函数,直到clearInterval方法取消循环 用clearInterval方法取消循环时,必须将setInterval方法的调用赋值给一个 ...
- 基于json的jquery地区联动探索
贴一个基于jquery联动的代码,相信这样的代码有一大把,就当是jquery的练手吧, 写这个东西的初衷是来之于新浪微博,在新浪微博帐号设置里面有个地区的选项,使用js写的,想把它的代码给截获下来,可 ...
- VB.NET与C# 语法区别展示
在学习VB.NET后发现,VB.NET与C#的语法主要的不同在两个部分,这两部分搞通了,那就游刃有余,迎刃而解了.现将其对比总结如下: 一.实体部分 (与VB相比,在C#和VB.NET中,实体的使用很 ...
- 【leetcode】 9. palindrome number
@requires_authorization @author johnsondu @create_time 2015.7.13 9:48 @url [palindrome-number](https ...
- SQL-重复记录查询的几种方法
1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select * from people where peopleId in (select peopleId from ...