iOS 自定义一个带有倒计时的弹出框

有时我们可能会有这么一种需求,就是当用户第一次进入app会有比较重要的信息提示希望用户仔细看一下,如果只是一个弹出框加上一个删除或者确定按钮,用户往往不会去阅读提示的内容,这样我们就可以在确认按钮加上倒计时,这样就会让用户感觉提示的信息应该比较重要,当倒计时结束才能删除或者确认。说了这么多其实功能有点类似启动页广告。先看一下需要的效果:

效果图

大致的样子就是这样,当然实现也不难,下面我们先看一下大致的控件,整体上来看就是自定义一个view,然后添加到window上就可以,这个view背景可以是button这样我们就可以设置点击事件,也可以是view,虽然我们的需求是不允许点击,但是自己还是用的button,而view上就是label+横线(可用label,view实现但注意一像素的设置)+高度不定的label+button+倒计时,整体上就是这样。下面就一步一步去实现。
首先我们先创建一个view,当然我们我已用xib提高开发效率,这里我用的代码,先自定义一个初始化方法,然后再创建需要的控件:

- (instancetype)initWithTitle:(NSString *)title messages:(NSString *)message cancelButtonTitle:(NSString *)cancelButtonTitle {
    self = [super init];
    if (self) {
        _titles = title;
        _message = message;
        _cancelTitle = cancelButtonTitle;
        self.backgroundColor = [UIColor whiteColor];
        self.alpha = 0;
        self.layer.masksToBounds = YES;
        self.layer.cornerRadius = 5.0;
    }
    return self;
}

在里面给view设置背景颜色,透明度等。
先来创建背景按钮,并且设置好相应的属性:

//添加背景
-(void)addBack {
    self.btnBack = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, ScreenWd, ScreenHt)];
    self.btnBack.backgroundColor = [UIColor blackColor];
    [self.btnBack addTarget:self action:@selector(gotoBackBtnClick:) forControlEvents:UIControlEventTouchUpInside];
    self.btnBack.alpha = 0;
}
//点击背景按钮
- (void)gotoBackBtnClick:(UIButton *)btn{
    NSLog(@"点击背景");
}

设置标题,这里使用懒加载的方式:

//添加头部提示
- (UILabel *)labTitle {
    if (!_labTitle) {
        _labTitle = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, ScreenWd-80, 20)];
        _labTitle.textAlignment = NSTextAlignmentCenter;
        _labTitle.text = _titles;
    }
    return _labTitle;
}

设置横线,我这里使用的是一高度,如果想设置为1像素,我们可以这样设置(参考:如何正确的绘制1像素的线):

//添加横线
- (UIImageView *)imgLine {
    if (!_imgLine) {
        _imgLine = [[UIImageView alloc] initWithFrame:CGRectMake(20, CGRectGetMaxY(self.labTitle.frame)+10, ScreenWd-80, 1)];
        _imgLine.backgroundColor = [UIColor colorWithWhite:0.925 alpha:1.000];
    }
    return _imgLine;
}

接下来的label需要计算行高:

//添加内容
- (UILabel *)labMessage {
    if (!_labMessage) {
        _labMessage = [[UILabel alloc] init];
        _labMessage.textColor = [UIColor colorWithWhite:0.259 alpha:1.000];
        _labMessage.textAlignment = NSTextAlignmentCenter;
        _labMessage.numberOfLines = 0;
        _labMessage.text = _message;
        _labMessage.font = FontSize;
        NSDictionary *attrs = @{NSFontAttributeName : FontSize};
        CGRect messageSize = [_message boundingRectWithSize:CGSizeMake(ScreenWd-80, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil];
        _labMessage.frame = CGRectMake(20, CGRectGetMaxY(self.imgLine.frame)+10, ScreenWd-80, messageSize.size.height);
    }
    return _labMessage;
}

最后就是button的设置,要注意坐标的计算:

//添加确定
- (UIButton *)cancelButton {
    if (!_cancelButton) {
        _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _cancelButton.backgroundColor = [UIColor colorWithWhite:0.976 alpha:1.000];
        _cancelButton.layer.masksToBounds = YES;
        _cancelButton.layer.cornerRadius = 3.0;
        _cancelButton.layer.borderWidth = 1.0;
        _cancelButton.layer.borderColor = [UIColor colorWithWhite:0.875 alpha:1.000].CGColor;
        [_cancelButton setTitle:_cancelTitle forState:UIControlStateNormal];
        [_cancelButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        _cancelButton.titleLabel.font = FontSize;
        [_cancelButton addTarget:self action:@selector(gotoCancelButtonClick:) forControlEvents:UIControlEventTouchUpInside];
        _cancelButton.frame = CGRectMake(20, CGRectGetMaxY(self.labMessage.frame)+10, ScreenWd-80, 30);
        
    }
    return _cancelButton;
}

然后根据之前写的倒计时,直接加上就可以了:

- (UIButton *)cancelButton {
    if (!_cancelButton) {
        [CJXTimer initWithGCD:3 beginState:^(int seconds){
            [_cancelButton setTitle:[NSString stringWithFormat:@"请认真阅读(%.2d)", seconds] forState:UIControlStateNormal];
            _cancelButton.userInteractionEnabled = NO;
        } endState:^{
            //设置按钮的样式
            [_cancelButton setTitle:_cancelTitle forState:UIControlStateNormal];
            _cancelButton.userInteractionEnabled = YES;
        }];
        _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _cancelButton.backgroundColor = [UIColor colorWithWhite:0.976 alpha:1.000];
        _cancelButton.layer.masksToBounds = YES;
        _cancelButton.layer.cornerRadius = 3.0;
        _cancelButton.layer.borderWidth = 1.0;
        _cancelButton.layer.borderColor = [UIColor colorWithWhite:0.875 alpha:1.000].CGColor;
        [_cancelButton setTitle:_cancelTitle forState:UIControlStateNormal];
        [_cancelButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        _cancelButton.titleLabel.font = FontSize;
        [_cancelButton addTarget:self action:@selector(gotoCancelButtonClick:) forControlEvents:UIControlEventTouchUpInside];
        _cancelButton.frame = CGRectMake(20, CGRectGetMaxY(self.labMessage.frame)+10, ScreenWd-80, 30);
        
    }
    return _cancelButton;
}

然后给view设置位置,位置可以直接在引用的时候设置,但是感觉那样不是很好,所以直接在这里设置bounds:

    self.bounds = CGRectMake(0, 0, ScreenWd - 40, CGRectGetMaxY(self.cancelButton.frame)+10);
    self.center = CGPointMake(ScreenWd/2, ScreenHt/2);
    [BaseWindow addSubview:self];

然后再设置弹出和消失动画效果以便以后引用:

- (void)show {
    self.bounds = CGRectMake(0, 0, ScreenWd - 40, CGRectGetMaxY(self.cancelButton.frame)+10);
    self.center = CGPointMake(ScreenWd/2, ScreenHt/2);
    [BaseWindow addSubview:self.btnBack];
    [BaseWindow addSubview:self];
    [UIView animateWithDuration:0.3 animations:^{
        self.btnBack.alpha = 0.4;
        self.alpha = 1.0;
    }];
}
/**
 *  视图隐藏
 */
- (void)dismiss{
    [UIView animateWithDuration:0.3 animations:^{
        self.btnBack.alpha = 0;
        self.alpha = 0;
    }completion:^(BOOL finished) {
        [self.btnBack removeFromSuperview];
        [self removeFromSuperview];
    }];
}

最后我们测试一下:

- (IBAction)popView:(id)sender {
    CJXAlertView *cjxView = [[CJXAlertView alloc]initWithTitle:@"提示" messages:@"注意啦!注意啦!这里的消息很重要。塞纳河畔 左岸的咖啡 我手一杯 品尝你的美 留下唇印的嘴 花店玫瑰 名字写错谁 告白气球 风吹到对街 微笑在天上飞 你说你有点难追 想让我知难而退 礼物不需挑最贵 只要香榭的落叶 喔 营造浪漫的约会 不害怕搞砸一切 拥有你就拥有 全世界 亲爱的 爱上你 从那天起 甜蜜的很轻易 亲爱的 别任性 你的眼睛 在说我愿意"cancelButtonTitle:@"确定"];
    [cjxView show];
}

正如预期的效果,如果感觉哪里不合适可以再调整一下。当然如果需要其他样式也可以这样一步一步设置,我这里封装的不算太好,因为需求的原因,没有做其他按钮的设置,但是这样基本可以满足需求了。
我是Demo

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

推荐阅读更多精彩内容