带有关闭按钮的alertView

灰太狼 2022-05-31 11:16 322阅读 0赞

概述

由于讨厌系统自带的alertView只能通过点击按钮才能关闭。你说万一按钮区域都是功能性的操作呢(这可不是我胡思乱想哦,要怪就产品的想法吧,呵呵哒),所以我们还是应该备有一个带有“X”(关闭按钮,为什么是叫X,因为X这个标志很明显嘛~)的alertView。

详细

代码下载:http://www.demodashi.com/demo/10917.html

一、程序实现

1、程序结构

B949195B-257D-4F01-8F2B-243092F029DF.png

2、实现思路与代码

XBAlertView是作为显示弹出框的入口,在初始化XBAlertView示例时,会将弹出框除了按钮部分全都设置好。而按钮部分采用UICollectionView来实现(因为有可能有多个按钮,这样方便扩展)。

  1. - (void)setupContentView{
  2. //title
  3. self.alertTitleLabel = [[UILabel alloc] init];
  4. self.alertTitleLabel.font = [UIFont boldSystemFontOfSize:17.0f];
  5. self.alertTitleLabel.textAlignment = NSTextAlignmentCenter;
  6. self.alertTitleLabel.frame = CGRectMake(TitleHorizontalOffset, TitleMarginTop, SelfWidth - TitleHorizontalOffset * 2, self.alertTitleLabel.font.lineHeight);
  7. [self addSubview:self.alertTitleLabel];
  8. //content
  9. CGFloat contentLabelWidth = SelfWidth - ContentHorizontalOffset * 2;
  10. CGFloat contentH = [self heightWithContent:_content byWidth:contentLabelWidth andFontSize:13 andLineSpacing:3];
  11. self.alertContentLabel = [[UILabel alloc] initWithFrame:CGRectMake(ContentHorizontalOffset, CGRectGetMaxY(self.alertTitleLabel.frame) + ContentMarginTop, contentLabelWidth, contentH)];
  12. self.alertContentLabel.numberOfLines = 0;
  13. self.alertContentLabel.textAlignment = NSTextAlignmentCenter;
  14. self.alertContentLabel.font = [UIFont systemFontOfSize:13.0f];
  15. [self addSubview:self.alertContentLabel];
  16. //self
  17. CGFloat selfHeight = TitleMarginTop + self.alertTitleLabel.font.lineHeight + ContentMarginTop + contentH + BtnMarginTop + kButtonHeight;
  18. CGFloat selfMarginLeft = (ScreenWidth - SelfWidth) / 2;
  19. self.frame = CGRectMake(selfMarginLeft, (ScreenHeight - selfHeight) / 2, SelfWidth, selfHeight);
  20. self.clipsToBounds = YES;
  21. self.layer.cornerRadius = 10.0;
  22. self.backgroundColor = [UIColor whiteColor];
  23. //collectionView
  24. [self addSubview:self.collectionView];
  25. _collectionView.delegate = self;
  26. _collectionView.dataSource = self;
  27. [_collectionView registerNib:[UINib nibWithNibName:@"XBAlertBtnCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:btnCellOneID];
  28. [_collectionView registerNib:[UINib nibWithNibName:@"XBAlertBtnCellTwo" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:btnCellTwoID];
  29. //X按钮
  30. UIButton *xButton = [UIButton buttonWithType:UIButtonTypeCustom];
  31. [xButton setImage:[UIImage imageNamed:@"btn_close_normal.png"] forState:UIControlStateNormal];
  32. [xButton setImage:[UIImage imageNamed:@"btn_close_selected.png"] forState:UIControlStateHighlighted];
  33. xButton.frame = CGRectMake(self.frame.size.width - 32, 0, 32, 32);
  34. [self addSubview:xButton];
  35. [xButton addTarget:self action:@selector(dismissAlert) forControlEvents:UIControlEventTouchUpInside];
  36. }

为了能够切合原生方式的调用,提供了-(void)addAction:(dispatch_block_t)actionBlock withTitle:(NSString*)title方法,该方法用于向XBAlertView添加按钮以及对应的响应block。

  1. -(void)addAction:(dispatch_block_t)actionBlock withTitle:(NSString*)title{
  2. if(actionBlock && ![self isBlankString:title]){
  3. [self.blockArray addObject:actionBlock];
  4. [self.btnTitleArray addObject:title];
  5. }
  6. }

调用后会先保存到数组当中。

在这之后,调用方调用XBAlertView的show方法进行展示。

  1. - (void)show
  2. {
  3. if(self.btnTitleArray.count == 0 || self.btnTitleArray.count > 2){
  4. //更新view的frame
  5. [self updateFrame];
  6. }
  7. [self.collectionView reloadData];
  8. UIViewController *topVC = [self appRootViewController];
  9. [topVC.view addSubview:self];
  10. }

show方法首先会根据两个数组是否有值来决定是否更新collectionView的frame。之后调用collectionView的reloadData,数据源就是这两个数组。这样加载后collectionView就有了需要展示的按钮。

然后获取[UIApplication sharedApplication].keyWindow.rootViewController,在这个控制器的view上添加上已经布局好的XBAlertView。

但是为了营造阴影效果,在XBAlertView被添加到父view之前,会调用以下方法创建一个遮罩层。这样就能达到显示的要求。

  1. - (void)willMoveToSuperview:(UIView *)newSuperview
  2. {
  3. if (newSuperview == nil) {
  4. return;
  5. }
  6. UIViewController *topVC = [self appRootViewController];
  7. if (!self.backImageView) {
  8. self.backImageView = [[UIView alloc] initWithFrame:topVC.view.bounds];
  9. self.backImageView.backgroundColor = [UIColor blackColor];
  10. self.backImageView.alpha = 0.6f;
  11. self.backImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
  12. }
  13. [topVC.view addSubview:self.backImageView];
  14. CGRect afterFrame = CGRectMake((CGRectGetWidth(topVC.view.bounds) - self.frame.size.width) * 0.5, (CGRectGetHeight(topVC.view.bounds) - self.frame.size.height) * 0.5, self.frame.size.width, self.frame.size.height);
  15. self.frame = afterFrame;
  16. [super willMoveToSuperview:newSuperview];
  17. }

那么接下来就是点击响应了,因为每个按钮就是collectionView的一个cell,所以按钮的点击就转为了cell的didSelectItemAtIndexPath方法。在该方法中根据索引从前面保存好的数组取出相对应的block,并调用

  1. - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
  2. dispatch_block_t block = self.blockArray[indexPath.row];
  3. block();
  4. [self dismissAlert];
  5. }

那么为了将隐藏弹出框封装到里面,会主动调用dismissAlert方法隐藏弹出框。

二、运行效果

下载解压后,直接用xcode打开,即可运行

4191AA2D-B0B8-4879-95E0-EF8016871A7B.png

19815664-01D6-4B66-896F-042BD5977F36.png

77C09C15-0105-4067-A237-CEACCD03CEFB.png

代码下载:http://www.demodashi.com/demo/10917.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

发表评论

表情:
评论列表 (有 0 条评论,322人围观)

还没有评论,来说两句吧...

相关阅读

    相关 带有关闭按钮alertView

    概述 由于讨厌系统自带的alertView只能通过点击按钮才能关闭。你说万一按钮区域都是功能性的操作呢(这可不是我胡思乱想哦,要怪就产品的想法吧,呵呵哒),所以我们还是应

    相关 JTabbedPane实现关闭按钮

     JTabbedPane如切换卡一般,大大的优化了布局,方便用户操作。Java默认的JTabbedPane添加tab时只会显示一个标题,咱们这里来给它实现关闭按钮,当鼠标移上这