iOS开发自定义弹出框实现思路

首先放两张旧版app用的提示框截图,之前这个是直接用MBProgressHUD做的,效果是有点丑。


旧版提示框截图1.png
旧版提示框截图2.png

然后再看看我们boss做的安卓版本的提示框:


安卓新版提示框截图1.png
安卓新版提示框截图2.png

不管是从用户体验还是界面美观角度来看,iOS都比不过Android。本来我也不想计较这么多的,毕竟我不是那么小心眼的人(呃,刚开始我是真不会)。可是老板他就要求你做,而且做出来的效果要和安卓的一模一样。刚开始我是这么跟老板说的:“这个对我来说确实有难度,我可能做不出这种效果。”,然后老板说了一句“你要是做不出来,我请你来干嘛?难道还需要我请一个外包来做这个吗?”,这句话很伤,真的伤;我只好要求给我点时间,一定要做出来,不能让老板怀疑我的能力,接着大概花了两天的时间,上网找各种弹出框、提示框资料,最后还是弄出来了。

在这里,首先要特别感谢一下贡献这个demo地址的前辈,
https://github.com/MacKaSL/HMPopUp
这是前辈的效果图:

HMPopUp效果.png

真的谢谢你,是这个demo给了我设计XLPopView弹出框的思路。
接着,来看看最后的效果:


新版效果.gif

下面说说实现思路:

一、创建XLPopView

1、首先想着外面要怎么调用这个弹出框方法?由于我这里一共有四种类型的弹出框样式,分别写了四个类方法供外面调用,其实归根结底调的还是里面的私有方法(这个思路就是从上面提供demo的前辈那里得来的,因为我的需求,我改了他很多东西),下面简单介绍一下第一种弹出框样式,这里只是提供一种思路。

/**
 *  第一种弹出框:固定提示title、右上角关闭按钮、下面确定按钮;中间提示文字可自定义
 *
 *  @param tipStr 中间提示文字
 *
 *  @return 弹出框
 */
+ (XLPopView *)popViewWithTipStr:(NSString *)tipStr;

2、类方法里面写什么?这里其实调用的是它自己的私有方法,私有方法里面的话我是自己写了,关键就在于承载容器的视图,承载器搞定了,接着就是往承载器里加东西,想加什么就加什么,比如,文本框、按钮、图片等等根据你的需求随意添加;如果需要添加什么点击事件可能就需要打开用户交互活着设置代理什么的,具体看个人需求。

+ (XLPopView *)popViewWithTipStr:(NSString *)tipStr {
    return [[self alloc] initWithTipStr:tipStr];
}

- (XLPopView *)initWithTipStr:(NSString *)tipStr {
    self = [super initWithFrame:[UIScreen mainScreen].bounds];
    if (self) {
        // 弹出框后面的背景视图
        UIView *shawdowView = [[UIView alloc] initWithFrame:self.bounds];
        shawdowView.backgroundColor  = [UIColor blackColor];
        shawdowView.alpha = 0.6;
        [self addSubview:shawdowView];
        
        // 承载容器的视图
        UIImageView *containerView = [[UIImageView alloc] initWithFrame:CGRectMake(20, SCREEN_HEIGHT*0.36, SCREEN_WIDTH-40, SCREEN_HEIGHT*0.28)];
        // 一定要打开用户交互下面的关闭按钮添加手势才有效果
        containerView.userInteractionEnabled = YES;
        containerView.layer.cornerRadius = 5.0f;
        containerView.clipsToBounds = YES;
        containerView.image = [UIImage imageNamed:@"XLPopView"];
        [self addSubview:containerView];
        _containerView = containerView;
        
        CGFloat cHeight = containerView.height;
        // 顶部label
        UILabel *topL = [UILabel new];
        topL.text = @"提示";
        topL.textColor = [UIColor whiteColor];
        topL.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:17.0];
        topL.textAlignment = NSTextAlignmentCenter;
        topL.frame = CGRectMake(_containerView.width/4, 10, _containerView.width/2, 30);
        [_containerView addSubview:topL];
        
        // 右上角删除按钮
        UIButton *closeBtn = [UIButton new];
        closeBtn.frame = CGRectMake(_containerView.width-45, 0, 50, 50);
        [closeBtn setBackgroundImage:[UIImage imageNamed:@"closeBtn"] forState:UIControlStateNormal];
        [closeBtn setBackgroundImage:[UIImage imageNamed:@"closeBtn"] forState:UIControlStateHighlighted];
        [closeBtn addTarget:self action:@selector(clickCloseBtn) forControlEvents:UIControlEventTouchUpInside];
        [_containerView addSubview:closeBtn];
        
        // topTitle与middleTitle 分割线
        UIView *topSeperateLine = [UIView new];
        topSeperateLine.frame = CGRectMake(0, cHeight/3+6, _containerView.width, 1);
        topSeperateLine.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.5];
        [_containerView addSubview:topSeperateLine];
        
        // 中间label
        UILabel *middleL = [UILabel new];
        middleL.text = tipStr;
        middleL.textColor = [UIColor whiteColor];
        middleL.numberOfLines = 0;
        middleL.font = [UIFont systemFontOfSize:14.0];
        middleL.textAlignment = NSTextAlignmentCenter;
        middleL.lineBreakMode = NSLineBreakByTruncatingMiddle;
        middleL.frame = CGRectMake(10, CGRectGetMaxY(topSeperateLine.frame), _containerView.width-20, cHeight*0.3);
        [_containerView addSubview:middleL];
        
        // 确认按钮
        UIButton *confirmBtn = [UIButton new];
        confirmBtn.frame = CGRectMake((_containerView.width-160)/2, CGRectGetMaxY(middleL.frame), 160, 40);
        confirmBtn.backgroundColor = [UIColor whiteColor];
        confirmBtn.titleLabel.font = [UIFont systemFontOfSize:14.0];
        confirmBtn.layer.cornerRadius = 5.0f;
        [confirmBtn setTitle:@"确 定" forState:UIControlStateNormal];
        [confirmBtn setTitleColor:[UIColor colorWithRed:36/255.0 green:160/255.0 blue:241/255.0 alpha:1.0] forState:UIControlStateNormal];
        [_containerView addSubview:confirmBtn];
        [confirmBtn addTarget:self action:@selector(clickCloseBtn) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
}

3、弹出框已经创建好了,要怎么显示出来?显示在哪里?这里写了一个方法放在.h文件,方便外面调用(注意:一般是放在self.view上,有时候self.view并不是最上面的窗口,有时候需要切换横竖屏,这个得根据情况做判断)。

/**
 *  展示在哪个视图上
 */
- (void)showInView:(UIView *)view {
    _containerView.alpha = 0;
    [view addSubview:self];
    _containerView.transform = CGAffineTransformMakeScale(0, 0);
    [UIView animateWithDuration:PRESENTATION_ANIMATION_DURATION
                          delay:0
         usingSpringWithDamping:1.0
          initialSpringVelocity:1
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         _containerView.alpha = 1.0f;
                         _containerView.transform = CGAffineTransformIdentity;
                     } completion:^(BOOL finished) {   
                     }];
}

4、有显示就有消失,消失方法是放在私有方法里面的,不让外面调用,当点击右上角删除(关闭)按钮或取消按钮弹出框消失。显示和消失这里用的动画我只写了一种符合自己需求的,如果有需要可以自己设置一个枚举类型的弹出和消失方式。

- (void)dismiss {
    [UIView animateWithDuration:DISMISS_ANIMATION_DURATION
                                  delay:0
                                options:UIViewAnimationOptionBeginFromCurrentState
                             animations:^{
                                 _containerView.alpha = 0.0;
                                 self.alpha = 0.0;
                             }
                             completion:^(BOOL finished) {
                                 [self removeFromSuperview];
                             }];
}

二、使用XLPopView

创建完了就应该知道怎么使用它了。

NSLog(@"第一种弹出框:固定提示title、右上角关闭按钮、下面确定按钮;中间提示文字可自定义。");
XLPopView *popView = [XLPopView popViewWithTipStr:@"这里可以自定义提示文字。"];
    [popView showInView:[UIApplication sharedApplication].keyWindow];

两句代码创建显示完毕。其中第四种样式点击确定有一个代理方法,实现代理方法可以根据需求跳转到指定页面,具体详情可查看完整demo

模拟效果.gif

说明:XLPopView是根据公司项目需求来写的,本想把一些相关的属性封装的更好一点,但后面想想又没这个必要,只是提供一种思路,这种提示框的东西无法做到用的人就能满足其需求,有些人需要的背景、字体、字体颜色大小、按钮...都可能不一样,所以就没有写了。

完整demo地址:
https://github.com/schnappiYep/XLPopViewDemo

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

推荐阅读更多精彩内容