iOS自定义alertView,继承自UIView,可以添加子视图,标题图片+文字

自定义alertView,继承自UIView,可以在消息区域添加子视图:addCustomerSubview

标题可以有图片+文字构成, 只支持两个按钮操作

// - 在需要alert的控制器调用 alertView show 方法

CustomAlertView *alertView = [[CustomAlertView alloc] initWithTitle:@"提示"
                                                        message:@"dylan_lwb_"
                                                       delegate:self
                                              cancelButtonTitle:@"确定"
                                              otherButtonTitles: nil];
    [alertView show];
    [alertView release];

// - 在项目里创建一个CustomAlertView分类, 把下边代码全部复制过去

<span style="font-family: Arial, Helvetica, sans-serif;">#if defined(__APPLE_CC__) && (__APPLE_CC__ >= 5549)</span>
#define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel(0,1)))
#else
#define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel))
#endif

#define SCREEN_WIDTH    [[UIScreen mainScreen] bounds].size.width
#define SCREEN_HEIGHT   [[UIScreen mainScreen] bounds].size.height
#define RGBA_COLOR(r, g, b, a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
#define kBCAlertViewPresentNotify   @"kBCAlertViewPresentNotify"  //alertview present notify

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@class CustomAlertView;

@protocol MBAlertViewDelegate <NSObject>

@optional

// - 代理方法
-(void)alertView:(CustomAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
-(void)alertViewClosed:(CustomAlertView *)alertView;
-(void)willPresentCustomAlertView:(UIView *)alertView;

// - 隐藏实用类弹出键盘
- (void)hideCurrentKeyBoard;

@end

@interface CustomAlertView : UIView {
}

@property (nonatomic, assign) id <MBAlertViewDelegate> delegate;
@property (nonatomic, assign) BOOL           isNeedCloseBtn;  // - 左上角带叉叉按钮
@property (nonatomic, retain) NSString       *title;
@property (nonatomic, retain) NSString       *message;
@property (nonatomic, retain) UIView         *backView;
@property (nonatomic, retain) UIView         *titleBackgroundView;
@property (nonatomic, retain) UILabel        *titleLabel;
@property (nonatomic, retain) UIImageView    *titleIcon;
@property (nonatomic, retain) NSMutableArray *customerViewsToBeAdd;

- (id)initWithTitle:(NSString*)title message:(NSString*)message delegate:(id)delegate cancelButtonTitle:(NSString*)cancelButtonTitle otherButtonTitles:(NSString*)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION;

-(void)initTitle:(NSString*)title message:(NSString*)message delegate:(id)del cancelButtonTitle:(NSString*)cancelBtnTitle otherButtonTitles:(NSString*)otherBtnTitles, ...NS_REQUIRES_NIL_TERMINATION;

- (void) show ;

// - 在alertview中添加自定义控件
- (void)addCustomerSubview:(UIView *)view;

+ (void)exChangeOut:(UIView *)changeOutView dur:(CFTimeInterval)dur;

+ (CustomAlertView *)defaultAlert;

@end

#import "CustomAlertView.h"
@interface CustomAlertView()

{
    BOOL _isShow;
}
@property (nonatomic, retain) NSString       *cancelButtonTitle;
@property (nonatomic, retain) NSMutableArray *otherButtonTitles;

@end

@implementation CustomAlertView

static const CGFloat mWidth  = 290;
static const CGFloat mHeight = 180;
static const CGFloat mMaxHeight    = 250;
static const CGFloat mBtnHeight    = 30;
static const CGFloat mBtnWidth     = 110;
static const CGFloat mHeaderHeight = 40;

+ (CustomAlertView *)defaultAlert
{
    static CustomAlertView *shareCenter = nil;
	if (!shareCenter)
    {
		shareCenter = [[CustomAlertView alloc] init];
	}
	return shareCenter;
}

- (NSMutableArray *)customerViewsToBeAdd
{
    if (_customerViewsToBeAdd == nil)
    {
        _customerViewsToBeAdd = [[NSMutableArray alloc] init];
    }

    return _customerViewsToBeAdd;
}

- (id)init
{
    self = [super initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT + 20)];
    if (self)
    {
        _isShow = NO;
    }
    return self;
}

- (id)initWithTitle:(NSString*)title message:(NSString*)message delegate:(id)del cancelButtonTitle:(NSString*)cancelBtnTitle otherButtonTitles:(NSString*)otherBtnTitles, ...
{
    self = [super initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT + 20)];
    if (self)
    {
        self.delegate = del;
        self.cancelButtonTitle = cancelBtnTitle;
        self.isNeedCloseBtn = NO;

        if (!_otherButtonTitles)
        {
            va_list argList;
            if (otherBtnTitles)
            {
                self.otherButtonTitles = [NSMutableArray array];
                [self.otherButtonTitles addObject:otherBtnTitles];
            }
            va_start(argList, otherBtnTitles);
            id arg;
            while ((arg = va_arg(argList, id)))
            {
                [self.otherButtonTitles addObject:arg];
            }
        }
        self.title = title;
        self.message = message;

    }
    return self;
}

-(void)initTitle:(NSString*)title message:(NSString*)message delegate:(id)del cancelButtonTitle:(NSString*)cancelBtnTitle otherButtonTitles:(NSString*)otherBtnTitles, ...
{
    if (self)
    {
        self.delegate = del;
        self.cancelButtonTitle = cancelBtnTitle;
        self.isNeedCloseBtn = NO;

        if (!_otherButtonTitles)
        {
            va_list argList;
            if (otherBtnTitles)
            {
                self.otherButtonTitles = [NSMutableArray array];
                [self.otherButtonTitles addObject:otherBtnTitles];
            }
            va_start(argList, otherBtnTitles);
            id arg;
            while ((arg = va_arg(argList, id)))
            {
                [self.otherButtonTitles addObject:arg];
            }
        }
        self.title = title;
        self.message = message;
    }
}

- (void) layoutSubviews
{
    [super layoutSubviews];

    for (UIView *view in [self subviews])
    {
        [view removeFromSuperview];
    }

    UIView *bgView = [[UIView alloc] initWithFrame:self.frame];
    [bgView setBackgroundColor:[UIColor blackColor]];
    [bgView setAlpha:0.4];
    [self addSubview:bgView];
    [bgView release];

    if (!_backView)
    {
        _backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, mWidth, mHeight)];
        _backView.opaque = NO;
        _backView.backgroundColor     = [UIColor whiteColor];
        _backView.layer.shadowOffset  = CGSizeMake(1, 1);
        _backView.layer.shadowRadius  = 2.0;
        _backView.layer.shadowColor   = [UIColor grayColor].CGColor;
        _backView.layer.shadowOpacity = 0.8;
        [_backView.layer setMasksToBounds:NO];
    }

    // - 设置头部显示区域
    // - 设置标题背景
    UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, mWidth, mHeaderHeight)];
    titleView.backgroundColor = RGBA_COLOR(36, 193, 64, 1);

    CGSize titleSize = CGSizeZero;
    if (self.title && [self.title length] > 0)
    {
        titleSize = [self.title sizeWithFont:[UIFont fontWithName:@"Helvetica-Bold" size:18.0f]];
    }
    if (titleSize.width > 0)
    {
        // - 标题图片
        CGFloat startX = (titleView.frame.size.width - 40 - titleSize.width) / 2;
        UIImageView *titleImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"xxxxx.png"]];
        titleImage.frame = CGRectMake(startX, (titleView.frame.size.height - 30) / 2, 30, 30);
        self.titleIcon = titleImage;

        [titleView addSubview:titleImage];
        [titleImage release];
        startX += 40;

        // - 标题
        UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(startX, (titleView.frame.size.height - 20) / 2, titleSize.width, 20)];

        //- 标题太长的话需要处理
        if (titleLabel.frame.size.width > 250)
        {
            titleLabel.frame = CGRectMake(50, (titleView.frame.size.height - 20) / 2, mWidth - 60, 20);

            titleImage.frame = CGRectMake(5, (titleView.frame.size.height - 30) / 2, 30, 30);

        }

        titleLabel.text = self.title;
        titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:18.0f];
        titleLabel.textColor = [UIColor whiteColor];
        titleLabel.backgroundColor = [UIColor clearColor];
        self.titleLabel = titleLabel;

        [titleView addSubview:titleLabel];
        [titleLabel release];
    }else
    {
        // - 标题图片
        UIImageView *titleImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"xxxxx.png"]];
        titleImage.frame = CGRectMake((titleView.frame.size.width - 30) / 2, (titleView.frame.size.height - 30) / 2, 30, 30);
        [titleView addSubview:titleImage];
        [titleImage release];
    }

    if (self.isNeedCloseBtn)
    {
        UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(mWidth-mHeaderHeight, 0, mHeaderHeight, mHeaderHeight)];
        btn.backgroundColor = [UIColor clearColor];
        [btn setImage:[UIImage imageNamed:@"btn_close_alertview.png"] forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(closeBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
        [titleView addSubview:btn];
        [btn release];
    }

    [_backView addSubview:titleView];
    self.titleBackgroundView = titleView;
    [titleView release];

    // - 设置消息显示区域
    UIScrollView *msgView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, mHeaderHeight, mWidth, (mHeight-mHeaderHeight * 2))];

    // - 设置背景颜色
    msgView.backgroundColor = [UIColor whiteColor];

    // - 内容
    CGSize messageSize = CGSizeZero;
    if (self.message && [self.message length]>0)
    {
        messageSize = [self.message sizeWithFont:[UIFont systemFontOfSize:16.0f] constrainedToSize:CGSizeMake(mWidth-20, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];

        if (messageSize.width > 0)
        {
            UILabel *msgLabel = [[UILabel alloc] init];
            msgLabel.font = [UIFont systemFontOfSize:16.0f];
            msgLabel.text = self.message;
            msgLabel.numberOfLines   = 0;
            msgLabel.textAlignment   = NSTextAlignmentCenter;
            msgLabel.backgroundColor = [UIColor clearColor];
            msgLabel.frame = CGRectMake(10, ((mHeight - mHeaderHeight * 2) - messageSize.height) / 2, mWidth-20, messageSize.height + 5);
            if(messageSize.height > mMaxHeight)
            {
                msgView.frame = CGRectMake(msgView.frame.origin.x, msgView.frame.origin.y, msgView.frame.size.width, mMaxHeight + 25);
                _backView.frame = CGRectMake(0, 0, mWidth, mHeaderHeight * 2 + msgView.frame.size.height);
                msgLabel.textAlignment = NSTextAlignmentLeft;
                msgLabel.frame = CGRectMake(10, 10, mWidth - 20, messageSize.height);
                msgView.contentSize = CGSizeMake(msgView.frame.size.width, msgLabel.frame.size.height + 20);
            }
            else if (messageSize.height > (mHeight-mHeaderHeight * 2) - 10)
            {
                msgView.frame = CGRectMake(msgView.frame.origin.x, msgView.frame.origin.y, msgView.frame.size.width, messageSize.height + 25);
                _backView.frame = CGRectMake(0, 0, mWidth, mHeaderHeight * 2 + msgView.frame.size.height);
                msgLabel.frame = CGRectMake(10, 10, mWidth - 20, messageSize.height + 5);
            }
            [msgView addSubview:msgLabel];
            [msgLabel release];
            [_backView addSubview:msgView];
        }
    }else{
        if (self.customerViewsToBeAdd && [self.customerViewsToBeAdd count] > 0)
        {
            CGFloat startY = 0;
            for (UIView *subView in self.customerViewsToBeAdd)
            {
                CGRect rect = subView.frame;
                rect.origin.y = startY;
                subView.frame = rect;
                [msgView addSubview:subView];
                startY += rect.size.height;
            }
            msgView.frame = CGRectMake(0, mHeaderHeight, mWidth, startY);
        }
        [_backView addSubview:msgView];
        _backView.frame = CGRectMake(0, 0, mWidth, msgView.frame.size.height + mHeaderHeight * 2 +20);
    }
    [msgView release];

    // - 设置按钮显示区域
    if (_otherButtonTitles != nil || _cancelButtonTitle != nil)
    {
        UIView *btnView = [[UIView alloc] initWithFrame:CGRectMake(0, _backView.frame.size.height-mHeaderHeight, mWidth, mHeaderHeight)];

        // - 如果只显示一个按钮,需要计算按钮的显示大小
        if (_otherButtonTitles == nil || _cancelButtonTitle == nil)
        {
            UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake((_backView.frame.size.width-mBtnWidth) /  2, 0, mBtnWidth, mBtnHeight)];
            btn.backgroundColor = RGBA_COLOR(36, 193, 64, 1);
            btn.titleLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0f];
            btn.titleLabel.textColor = [UIColor whiteColor];
            [btn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
            if (_otherButtonTitles == nil && _cancelButtonTitle != nil)
            {
                [btn setTitle:_cancelButtonTitle forState:UIControlStateNormal];
            } else
            {
                [btn setTitle:[_otherButtonTitles objectAtIndex:0] forState:UIControlStateNormal];
            }
            btn.tag = 0;
            btn.layer.cornerRadius = 5;
            [btnView addSubview:btn];
            [btn release];
        }
        else if(_otherButtonTitles && [_otherButtonTitles count] == 1)
        {
            // - 显示两个按钮
            // - 设置确定按钮的相关属性
            CGFloat startX = (_backView.frame.size.width-mBtnWidth*2-20)/2;
            UIButton *otherBtn = [[UIButton alloc]initWithFrame:CGRectMake(startX, 0, mBtnWidth, mBtnHeight)];
            otherBtn.backgroundColor = RGBA_COLOR(36, 193, 64, 1);
            otherBtn.titleLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0f];
            otherBtn.titleLabel.textColor = [UIColor whiteColor];
            [otherBtn setTitle:[_otherButtonTitles objectAtIndex:0] forState:UIControlStateNormal];
            otherBtn.layer.cornerRadius = 5;
            [otherBtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
            otherBtn.tag = 0;
            [btnView addSubview:otherBtn];
            [otherBtn release];
            startX += mBtnWidth+20;

            // - 设置取消按钮的相关属性
            UIButton *cancelBtn = [[UIButton alloc]initWithFrame:CGRectMake(startX, 0, mBtnWidth, mBtnHeight)];
            cancelBtn.backgroundColor = RGBA_COLOR(36, 193, 64, 1);
            cancelBtn.titleLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0f];
            cancelBtn.titleLabel.textColor = [UIColor whiteColor];
            [cancelBtn setTitle:_cancelButtonTitle forState:UIControlStateNormal];
            cancelBtn.layer.cornerRadius = 5;
            [cancelBtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
            cancelBtn.tag = 1;
            [btnView addSubview:cancelBtn];
            [cancelBtn release];
        }
        [_backView addSubview: btnView];
        [btnView release];
    }
    else
    {
        CGRect rc = _backView.frame;
        rc.size.height -= mHeaderHeight;
        _backView.frame = rc;
    }

    UIControl *touchView = [[UIControl alloc] initWithFrame:self.frame];
    [touchView addTarget:self action:@selector(touchViewClickDown) forControlEvents:UIControlEventTouchDown];
    touchView.frame = self.frame;
    [self addSubview:touchView];
    [touchView release];
    _backView.center = self.center;

    [self addSubview:_backView];

    if (!_isShow)
        [CustomAlertView exChangeOut:_backView dur:0.5];
    if (self.delegate)
    {
        if ([self.delegate respondsToSelector:@selector(willPresentCustomAlertView:)])
        {
            [self.delegate willPresentCustomAlertView:self];
        }

        [[NSNotificationCenter defaultCenter] postNotificationName:kBCAlertViewPresentNotify object:nil userInfo:nil];
    }
}
- (void)touchViewClickDown
{
    if (self.delegate)
    {
        if ([self.delegate respondsToSelector:@selector(hideCurrentKeyBoard)])
        {
            [self.delegate hideCurrentKeyBoard];
        }
    }
}

// - 在消息区域设置自定义控件
- (void)addCustomerSubview:(UIView *)view
{
    [self.customerViewsToBeAdd addObject:view];
}

- (void)buttonClicked:(id)sender
{
    UIButton *btn = (UIButton *) sender;
    _isShow = NO;
    if (btn)
    {
        if (self.delegate && [self.delegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)])
        {
            [self.delegate alertView:self clickedButtonAtIndex:btn.tag];
        }
        [self removeFromSuperview];
    }
}

- (void)closeBtnClicked:(id)sender
{
    _isShow = NO;
    if (self.delegate && [self.delegate respondsToSelector:@selector(alertViewClosed:)])
    {
        [self.delegate alertViewClosed:self];
    }
    [self removeFromSuperview];
}

- (void)show
{
    [self layoutSubviews];
    if (!_isShow)
        [[[UIApplication sharedApplication].delegate window]  addSubview:self];
    _isShow = YES;
}

- (void)dealloc
{
    [_backView release];
    [_customerViewsToBeAdd release];
    self.titleLabel = nil;
    self.titleBackgroundView = nil;
    self.titleIcon = nil;

    [super dealloc];
}

// - alertview弹出动画
+ (void)exChangeOut:(UIView *)changeOutView dur:(CFTimeInterval)dur
{
    CAKeyframeAnimation * animation;
    animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];

    animation.duration = dur;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;

    NSMutableArray *values = [NSMutableArray array];

    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9, 0.9)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)]];

    animation.values = values;
    animation.timingFunction = [CAMediaTimingFunction functionWithName: @"easeInEaseOut"];

    [changeOutView.layer addAnimation:animation forKey:nil];
}

@end
时间: 2024-11-03 01:36:18

iOS自定义alertView,继承自UIView,可以添加子视图,标题图片+文字的相关文章

iOS开发-自定义重用机制给ScrollerView添加子视图

其实这个问题我很早就想过,只是没有通过去敲代码实现,昨天有人提起,我就巧了一下 不知道大家打印郭tableview:cellforrow中cell初始的次数,也就是重用池中的cell个数,这个是固定的,比如屏幕最多可以显示4个cell那么重用池个数可能为5个6个或者7左右,我就想了如果scrollview去实现,子视图也应该是有一个个数的,那么如何去实现重用池呢?我想到了数组,可变数组,我在loadview中将scrollview的可滑动区域设置为10000,然后给scrollview每隔20个

关于cell中添加子视图 复用重叠问题的解决方法

问题本质: 因为你要添加的子视图并不是在自定义的cell中实现的,而是根据系统给的UITableViewCell这个类创建的实例,每次进图 cellForRow方法都会创建一个cell,每次都要创建一个子视图添(button,label之类的)加进去,会给占用很大的内存,所以采用了复 用的方法,但是问题就来了,当cell超出界面,从队列中拿过来复用的时候,其中子视图的内容并没有消除,这样你会原来的基础上再创建一个子视图添加上去 遮住了原来的视图,一般视图都是透明的这样的话就变成了一层层的叠加.

精通IOS-在表单元中添加子视图

#import <UIKit/UIKit.h> @interface NameAndColorCellTableViewCell : UITableViewCell @property(copy,nonatomic) NSString *name; @property(copy,nonatomic) NSString *color; @end NameAndColorCellTableViewCell.h // // NameAndColorCellTableViewCell.m // Tab

新浪微博开发-添加子视图控制器&amp;设置颜色

一.添加子视图控制器 二.设置颜色 设置颜色:两种方法 一种较为繁琐,详见视频 第二种: //设置颜色 self.tabBar.tintColor = UIColor.orangeColor()

在UIViewController的view上添加子视图不显示

第一种方式:通过代码方式创建视图控制器UIViewController,添加子视图,需要留意创建视图的size,如果是为0是看不到的 第二种方式:xib或storyboard方式创建视图控制器UIViewController,需要留意xib是否与视图变量之间建立的关系,没有建立关系子视图是添加到视图view中,但是就是不能系显示. 如图:

动态添加子视图 UIView 的正确方法

很多时候哥比较喜欢用代码添加视图,特别是要同时加很多UIView时,而且跟 xib 比起来代码更容易管理,在多人的项目中代码不容易 conflict. 但小牛哥最近发现很多新人都不太清楚正确的使用方法,以下是哥的一些总结,有何不妥欢迎大家一起讨论: (前提条件是这样的:有一个 View Controller  和相应的 xib 文件,我们需要为这个controller 动态加上其他的子视图) UIViewController 中动态添加 UIView 正确的步骤应该是: 1. 在 viewDid

自定义flex组件使用标签方式添加子组件

一般情况下,当我们写了一个继承自flex组件并往里面添加了子组件,然后想用标签等方式添加子组件时候报错了,那如何解决这一的问题,自定义组件代码如下: <?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">

UIView 添加子视图的常用方法

1.  - (void)addSubview:(UIView *)view 这是最常用的方法有两个注意点 参数view可以是nil,运行不会报错,当然,父视图的subViews也不会增加. 此方法增加的view层级当前是最高的,也就是最靠外. 2.  - (void)insertSubview:(UIView *)view atIndex:(NSInteger)index; 父视图的所有的子视图的index默认是从0开始的. index如果赋了负数,执行不会报错,但添加会失败. 如果index值

iOS 为移动中的UIView(UIButton )添加点击事件

高高兴兴迎接新的产品新需求,满心欢喜的开始工作,结果研究了一下午才发现,是自己想的太简单了,是我太单纯呀. 需求是这样的类似下雪的效果,随机产生一些小雪花,然后每个雪花可以点击到下个页面. 接到需求之后我的首先想法就是用button实现不久可以了,多简单点事情,结果实践之后就知道自己多么的无知了,在移动中的button根本没有办法接收点击事件. 然后同事给出了一种解决办法,通过手势获取点击的位置,然后遍历页面上的控件,如果在这个范围内就点击成功.通过这个想法我尝试用frame来实现需求,然后发现