iOS 仿系統(tǒng)UIAlertController高效版

最近封裝了一個(gè)AlertController,完全按照系統(tǒng)的思路進(jìn)行封裝屎蜓,省去了學(xué)習(xí)成本,且自定義程度遠(yuǎn)遠(yuǎn)高于系統(tǒng)的钥勋。說(shuō)不多說(shuō)炬转,上代碼咯!
下載地址先附上

#import <UIKit/UIKit.h>

/**樣式*/
@interface BDNomalAlertActionStyle : NSObject

/**標(biāo)題顏色*/
@property (nonatomic,strong)UIColor *titleColor;
/**標(biāo)題大小*/
@property (nonatomic,strong)UIFont *titleFont;
/**背景色*/
@property (nonatomic,strong)UIColor *bgColor;

@end

@interface BDNomalAlertAction : NSObject

@property (nonatomic,strong,readonly)BDNomalAlertActionStyle *style;
@property (nonatomic,copy,readonly)NSString *title;

+ (instancetype)actionWithTitle:(NSString *)title style:(BDNomalAlertActionStyle*)style handler:(void (^)(BDNomalAlertAction *action))handler;

@end

@interface BDNomalAlertView : UIView

+ (instancetype)alertControllerWithTitle:(NSString *)title message:(NSString *)message;

/**之間的距離 默認(rèn)為10*/
@property (nonatomic,assign)CGFloat actionBtnMargin;
/**左右兩邊的間距 默認(rèn)為0*/
@property (nonatomic,assign)CGFloat actionBtnLeftInset;
/**展示按鈕的最大寬度算灸,主要是為了美觀*/
@property (nonatomic,assign,readonly)CGFloat actionBtnMaxWidth;
- (void)addAction:(BDNomalAlertAction *)action;

- (void)showAlertView;

@end

各位小伙伴們扼劈,是不是跟系統(tǒng)的一樣樣的。動(dòng)畫效果高仿系統(tǒng)的菲驴。

一共分為三個(gè)類:

/**
這個(gè)是樣式模型荐吵,決定了你的操作按鈕長(zhǎng)的樣子,開(kāi)發(fā)者還可以繼續(xù)添加屬性即可
*/
@interface BDNomalAlertActionStyle : NSObject

而且提供了最常規(guī)的樣式類方法快速創(chuàng)建

/**取消樣式*/
+ (instancetype)cancelNomalStyle;
/**確定樣式*/
+ (instancetype)sureNomalStyle;

第二個(gè)是操作Action,也是仿照了系統(tǒng)進(jìn)行設(shè)計(jì)的先煎,以下是代碼:

@interface BDNomalAlertAction ()

@property (nonatomic,copy)void (^actionHandler)(BDNomalAlertAction*action);

@end

@implementation BDNomalAlertAction

+ (instancetype)actionWithTitle:(NSString *)title style:(BDNomalAlertActionStyle*)style handler:(void (^)(BDNomalAlertAction *action))handler
{
    return [[BDNomalAlertAction alloc]initWithTitle:title style:style handler:handler];
}

-(instancetype)initWithTitle:(NSString*)title style:(BDNomalAlertActionStyle*)style handler:(void (^)(BDNomalAlertAction *action))handler
{
    self = [super init];
    if(self){
        _title = title;
        _style = style;
        _actionHandler = handler;
    }
    return self;
}

@end

BDNomalAlertView是最關(guān)鍵的了贼涩,不廢話了,直接上了薯蝎,

@interface BDNomalAlertView ()

@property (nonatomic,weak)UIView *contentView;
@property (nonatomic,weak)UIView *actionView;
@property (nonatomic,strong)NSMutableArray *actionArray;

@end

@implementation BDNomalAlertView

+ (instancetype)alertControllerWithTitle:(NSString *)title message:(NSString *)message
{
    return [[BDNomalAlertView alloc]initWithFrame:[UIScreen mainScreen].bounds title:title message:message];
}

-(NSMutableArray *)actionArray
{
    if(!_actionArray){
        _actionArray = [NSMutableArray array];
    }
    return _actionArray;
}

-(instancetype)initWithFrame:(CGRect)frame title:(NSString*)title message:(NSString *)message
{
    self = [super initWithFrame:frame];
    if(self){
        _actionBtnMargin = 10;
        _actionBtnLeftInset = 0;
        _actionBtnMaxWidth = 100;
        self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4];
        CGFloat contentWidth = 250;
        if(SCREEN_WIDTH == 375){
            contentWidth = 280;
        }else if (SCREEN_WIDTH > 375){
            contentWidth = 320;
        }
        
        CGFloat contentActionHeight = 70;
        CGFloat contentTitleHeight = 0;
        CGFloat contentMessageHeight = 0;
        if(title.length > 0){
            contentTitleHeight = [title boundingRectWithSize:CGSizeMake(contentWidth-2*ALERT_LEFT_MARGIN, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:15]} context:nil].size.height+2+2*12;
        }
        if(message.length >0){
            contentMessageHeight = [message boundingRectWithSize:CGSizeMake(contentWidth-2*ALERT_LEFT_MARGIN, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil].size.height+2+2*15;
        }
        CGFloat contentHeight = contentActionHeight+contentTitleHeight+contentMessageHeight;
        UIView *contentView = [[UIView alloc]initWithFrame:CGRectMake((frame.size.width-contentWidth)*0.5, (frame.size.height-contentHeight)*0.5, contentWidth, contentHeight)];
        contentView.backgroundColor = [UIColor whiteColor];
        self.contentView = contentView;
        [self addSubview:contentView];
        [contentView.layer setCornerRadius:5];
        [contentView.layer setMasksToBounds:YES];

        CGRect titleViewFrame = CGRectZero;
        CGRect messageViewFrame = CGRectZero;
        CGRect actionViewFrame = CGRectZero;
        //添加標(biāo)題
        if(contentTitleHeight != 0){
            titleViewFrame = CGRectMake(0, 0, contentWidth, contentTitleHeight);
            actionViewFrame = CGRectMake(0, CGRectGetMaxY(titleViewFrame), contentWidth, contentActionHeight);
            UIView *titleView = [[UIView alloc]initWithFrame:titleViewFrame];
            [contentView addSubview:titleView];
            
            UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(ALERT_LEFT_MARGIN, 12, titleView.width-2*ALERT_LEFT_MARGIN, titleView.height-2*12)];
            titleLabel.textColor = [UIColor colorWithRed:1.0*51/255 green:1.0*51/255 blue:1.0*51/255 alpha:1.0];
            titleLabel.font = [UIFont boldSystemFontOfSize:15];
            titleLabel.text = title;
            titleLabel.numberOfLines = 0;
            titleLabel.textAlignment = NSTextAlignmentCenter;
            [titleView addSubview:titleLabel];
            
            UIView *titleLine = [[UIView alloc]initWithFrame:CGRectMake(0, titleView.height-0.8, titleView.width, 0.8)];
            titleLine.backgroundColor = [UIColor colorWithRed:1.0*225/255 green:1.0*225/255 blue:1.0*225/255 alpha:1.0];
            [titleView addSubview:titleLine];
        }
        //添加內(nèi)容
        if(contentMessageHeight != 0){
            messageViewFrame = CGRectMake(0, CGRectGetMaxY(titleViewFrame), contentWidth, contentMessageHeight);
            actionViewFrame = CGRectMake(0, CGRectGetMaxY(messageViewFrame), contentWidth, contentActionHeight);
            UIView *messageView = [[UIView alloc]initWithFrame:messageViewFrame];
            [contentView addSubview:messageView];
            
            UILabel *messageLabel = [[UILabel alloc]initWithFrame:CGRectMake(ALERT_LEFT_MARGIN, 15, messageView.width-2*ALERT_LEFT_MARGIN, messageView.height-2*15)];
            messageLabel.numberOfLines = 0;
            messageLabel.textColor = [UIColor colorWithRed:1.0*102/255 green:1.0*102/255 blue:1.0*102/255 alpha:1.0];;
            messageLabel.textAlignment = NSTextAlignmentCenter;
            messageLabel.text = message;
            messageLabel.font = [UIFont systemFontOfSize:14];
            [messageView addSubview:messageLabel];
        }
        UIView *actionView = [[UIView alloc]initWithFrame:actionViewFrame];
        self.actionView = actionView;
        [contentView addSubview:actionView];
        
    }
    return self;
}


- (void)addAction:(BDNomalAlertAction *)action
{
    [self.actionArray addObject:action];
    NSInteger actionIndex = self.actionView.subviews.count;
    BDUnHightedBtn *button = [[BDUnHightedBtn alloc]init];
    button.tag = actionIndex;
    BDNomalAlertActionStyle *style = action.style;
    [button setTitle:action.title forState:UIControlStateNormal];
    UIFont *btnFont = [UIFont systemFontOfSize:15];
    UIColor *btnColor = [UIColor colorWithRed:1.0*51/255 green:1.0*51/255 blue:1.0*51/255 alpha:1.0];
    if(style.titleFont){
        btnFont = style.titleFont;
    }
    if(style.titleColor){
        btnColor = style.titleColor;
    }
    
    button.titleLabel.font = btnFont;
    [button setTitleColor:btnColor forState:UIControlStateNormal];
    if(style.bgColor){
        [button setBackgroundColor:style.bgColor];
    }
    [button.layer setCornerRadius:3];
    [button.layer setMasksToBounds:YES];
    [self.actionView addSubview:button];
    [button addTarget:self action:@selector(clickActionButton:) forControlEvents:UIControlEventTouchUpInside];
    
}

- (void)clickActionButton:(BDUnHightedBtn*)button
{
    BDNomalAlertAction *action = self.actionArray[button.tag];
    WEAK_SELF(action);
    if(action.actionHandler){
        action.actionHandler(weakaction);
    }
    [self dismissAnimation];
}

- (void)showAlertView
{
    //設(shè)置actionview中的button的frame
    NSInteger count = self.actionView.subviews.count;
    CGFloat leftInset = _actionBtnLeftInset;
    
    CGFloat actionBtnWidth = (self.actionView.width - ((count-1)*_actionBtnMargin)-(2*leftInset))/count;
    if(actionBtnWidth >_actionBtnMaxWidth){
        actionBtnWidth = _actionBtnMaxWidth;
        //那么需要調(diào)整初始x
       leftInset = (self.actionView.width - (actionBtnWidth*count+ (count-1)*_actionBtnMargin))*0.5;
    }
    
    CGFloat actionBtnHeight = self.actionView.height-2*15;
    for (int i = 0; i<self.actionView.subviews.count; i++) {
        CGFloat actionBtnX = leftInset+(actionBtnWidth+_actionBtnMargin)*I;
        BDUnHightedBtn *button = self.actionView.subviews[I];
        button.frame = CGRectMake(actionBtnX, 15, actionBtnWidth, actionBtnHeight);
    }
    [self animationAlert:self.contentView];
    [[UIApplication sharedApplication].keyWindow addSubview:self];
    
}


- (void)animationAlert:(UIView *)view
{
    CAKeyframeAnimation *popAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    popAnimation.duration = 0.25;
    popAnimation.values = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2f, 1.2f, 1.0f)],
                            [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.0f)],
                            [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.05f, 1.05f, 1.05f)],
                            [NSValue valueWithCATransform3D:CATransform3DIdentity]];
    popAnimation.keyTimes = @[@0.0f, @0.2f, @0.4f, @1.0f];
    popAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
                                     [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
                                     [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [view.layer addAnimation:popAnimation forKey:nil];
    
}

- (void)dismissAnimation
{
    [UIView animateWithDuration:0.25 animations:^{
        self.alpha = 0;
    }];
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    scaleAnimation.toValue = [NSNumber numberWithFloat:0.4];
    scaleAnimation.duration = 0.3f;
    scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.contentView.layer addAnimation:scaleAnimation forKey:nil];
    [BDPublicWays outTimeShow:0.25 action:^{
        [self removeFromSuperview];
    }];
}

點(diǎn)擊這里下載
放心遥倦,能夠正常釋放,不存在內(nèi)存泄露占锯!喜歡的話袒哥,點(diǎn)個(gè)贊吧

下面是效果圖


IMG_0526.PNG
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市消略,隨后出現(xiàn)的幾起案子堡称,更是在濱河造成了極大的恐慌,老刑警劉巖艺演,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件却紧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钞艇,警方通過(guò)查閱死者的電腦和手機(jī)啄寡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)哩照,“玉大人挺物,你說(shuō)我怎么就攤上這事∑。” “怎么了识藤?”我有些...
    開(kāi)封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)次伶。 經(jīng)常有香客問(wèn)我痴昧,道長(zhǎng),這世上最難降的妖魔是什么冠王? 我笑而不...
    開(kāi)封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任赶撰,我火速辦了婚禮,結(jié)果婚禮上柱彻,老公的妹妹穿的比我還像新娘豪娜。我一直安慰自己,他們只是感情好哟楷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布瘤载。 她就那樣靜靜地躺著,像睡著了一般卖擅。 火紅的嫁衣襯著肌膚如雪鸣奔。 梳的紋絲不亂的頭發(fā)上墨技,一...
    開(kāi)封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音挎狸,去河邊找鬼扣汪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伟叛,可吹牛的內(nèi)容都是我干的私痹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼统刮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了账千?” 一聲冷哼從身側(cè)響起侥蒙,我...
    開(kāi)封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎匀奏,沒(méi)想到半個(gè)月后鞭衩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娃善,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年论衍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片聚磺。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡坯台,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瘫寝,到底是詐尸還是另有隱情蜒蕾,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布焕阿,位于F島的核電站咪啡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏暮屡。R本人自食惡果不足惜撤摸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望褒纲。 院中可真熱鬧准夷,春花似錦、人聲如沸外厂。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汁蝶。三九已至渐扮,卻和暖如春论悴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背墓律。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工膀估, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耻讽。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓察纯,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親针肥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饼记,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明先生_X自主閱讀 15,981評(píng)論 3 119
  • 名師指路慰枕,貴人相助具则; 親人支持,小人刺激具帮。 早安
    心心筑夢(mèng)閱讀 353評(píng)論 0 0
  • 風(fēng)流雅致真年少博肋, 海上仙島元夕。 雨花紛擾蜂厅,閃閃漁火繞匪凡, 一天煙碧。 舞動(dòng)魚龍掘猿,射夜幕病游, 飛騰爪擲。 石街道术奖,蓮燈...
    斷紅塵閱讀 174評(píng)論 0 0
  • 今天和他們一起回娘家采记,媽媽早已準(zhǔn)備好餃子餡并且和好面等著我們佣耐。我的肚子疼不能幫他們包餃子,這個(gè)時(shí)候外甥女藝然...
    笑川的玫瑰花園閱讀 341評(píng)論 0 1