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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容