????????一般來說念逞,自定義彈出視圖會遇到三個問題:
(1)按鈕個數(shù)及按鈕內(nèi)容變化問題
(2)彈出方式變化問題
(3)內(nèi)容與頁面綁定時履羞,內(nèi)容更新問題
? ? ? ? 對于第一個問題荸百,如果說彈出框只需要展示固定的幾個按鈕的話竟坛,那么此問題可以忽略了哪自。類似于系統(tǒng)的alertView灾测,UIAlertView會根據(jù)我們提供的title個數(shù)來展現(xiàn)不同的樣式尔苦,我們也可以以此思路來進行設計。既然需要根據(jù)按鈕title的個數(shù)來決定樣式行施,那么允坚,首先要做的就是收集到所填寫的titles,網(wǎng)上給出的方法有很多而且講述的也很詳細蛾号,這里給出一種常見的收集方式:
- (void)showAlertViewWithDescription:(NSString*)description withAction:(void(^)(NSInteger))blcok WithTitles:(NSString*)title, ...NS_REQUIRES_NIL_TERMINATION;
- (void)showAlertViewWithDescription:(NSString*)description withAction:(void(^)(NSInteger))blcok WithTitles:(NSString*)title, ...
{
? ? // 收集titles
? ? va_list args;
? ? va_start(args, title);
? ? NSMutableArray *titlesArray = [NSMutableArray array];
? ? for(NSString*str = title; str !=nil; str =va_arg(args,NSString*)) {
? ? ? ? [titlesArrayaddObject:str];
? ? }
? ? // 根據(jù)title的個數(shù)確定UI樣式
? ? [self configureUIWithDescription:description withTitles:titlesArray];
}
? ? ? ? 獲取到title之后稠项,就可以按照需求方式來進行樣式設計了。
? ? ? ? 對于彈出方式鲜结,我們可以使用一個enum來進行管理展运,然后根據(jù)需要來進行切換,本文會給出兩種彈出方式精刷,一種是通過UIDynamicBehavior中的snap動畫拗胜,一種是簡單的漸隱顯示:
// !!!: 顯示 & 關(guān)閉 alertView
- (void)showAlertView
{
? ? switch (self.showStyle) {
? ? ? ? case DynamicAlertViewShowStyleSnap:
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(!_dynamicAnimator) {
? ? ? ? ? ? ? ? ? ? self.center=CGPointMake(kScreenWidth/2, -alertViewHeight);
? ? ? ? ? ? ? ? ? ? self.alpha=1;
? ? ? ? ? ? ? ? ? ? _dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:window];
? ? ? ? ? ? ? ? ? ? UISnapBehavior *snapBehavior = [[UISnapBehavior alloc] initWithItem:self snapToPoint:window.center];
? ? ? ? ? ? ? ? ? ? snapBehavior.damping=0.5;
? ? ? ? ? ? ? ? ? ? [_dynamicAnimatoraddBehavior:snapBehavior];
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? break;
? ? ? ? case DynamicAlertViewShowStyleAppear:
? ? ? ? ? ? {
? ? ? ? ? ? ? ? self.center= window.center;
? ? ? ? ? ? ? ? self.transform = CGAffineTransformMakeScale(0.7, 0.7);
? ? ? ? ? ? ? ? self.alpha=0;
? ? ? ? ? ? ? ? __weaktypeof(self) weakSelf =self;
? ? ? ? ? ? ? ? [UIView animateWithDuration:.35 delay:0 usingSpringWithDamping:.5 initialSpringVelocity:.5 options:0 animations:^{
? ? ? ? ? ? ? ? ? ? weakSelf.alpha=1;
? ? ? ? ? ? ? ? ? ? weakSelf.transform = CGAffineTransformIdentity;
? ? ? ? ? ? ? ? }completion:^(BOOLfinished) {
? ? ? ? ? ? ? ? ? ? if(finished) {? }
? ? ? ? ? ? ? ? }];
? ? ? ? ? ? }
? ? ? ? ? ? break;
? ? ? ? default:
? ? ? ? ? ? break;
? ? }
}
- (void)hiddenAlertView
{
? ? switch (self.showStyle) {
? ? ? ? case DynamicAlertViewShowStyleSnap:
? ? ? ? {
? ? ? ? ? ? __weaktypeof(self) weakSelf =self;
? ? ? ? ? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
? ? ? ? ? ? ? ? UISnapBehavior*snapBehavior =_dynamicAnimator.behaviors.lastObject;
? ? ? ? ? ? ? ? snapBehavior.snapPoint=CGPointMake(kScreenWidth/2,kScreenHeight+alertViewHeight);
? ? ? ? ? ? ? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.35 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
? ? ? ? ? ? ? ? ? ? __strongtypeof(self) strongSelf = weakSelf;
? ? ? ? ? ? ? ? ? ? [strongSelf->_dynamicAnimatorremoveAllBehaviors];
? ? ? ? ? ? ? ? ? ? strongSelf->_dynamicAnimator=nil;
? ? ? ? ? ? ? ? ? ? [strongSelf->_bgCoverMaskViewremoveFromSuperview];
? ? ? ? ? ? ? ? ? ? strongSelf->_bgCoverMaskView=nil;
? ? ? ? ? ? ? ? ? ? weakSelf.center=CGPointMake(kScreenWidth/2, -alertViewHeight);
? ? ? ? ? ? ? ? ? ? [weakSelfremoveFromSuperview];
? ? ? ? ? ? ? ? });
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? ? ? break;
? ? ? ? case DynamicAlertViewShowStyleAppear:
? ? ? ? {
? ? ? ? ? ? __weaktypeof(self) weakSelf =self;
? ? ? ? ? ? dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
? ? ? ? ? ? ? ? [UIView animateWithDuration:.35 animations:^{
? ? ? ? ? ? ? ? ? ? weakSelf.alpha=0;
? ? ? ? ? ? ? ? ? ? weakSelf.transform=CGAffineTransformMakeScale(.7,.7);
? ? ? ? ? ? ? ? }completion:^(BOOLfinished) {
? ? ? ? ? ? ? ? ? ? __strongtypeof(self) strongSelf = weakSelf;
? ? ? ? ? ? ? ? ? ? if(finished) {
? ? ? ? ? ? ? ? ? ? ? ? [strongSelf->_bgCoverMaskViewremoveFromSuperview];
? ? ? ? ? ? ? ? ? ? ? ? strongSelf->_bgCoverMaskView=nil;
? ? ? ? ? ? ? ? ? ? ? ? weakSelf.transform=CGAffineTransformIdentity;
? ? ? ? ? ? ? ? ? ? ? ? [weakSelfremoveFromSuperview];
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }];
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? ? ? break;
? ? ? ? default:
? ? ? ? ? ? break;
? ? }
}????
? ? ? ? 在項目開發(fā)過程中,有時在向用戶展示彈出框時怒允,上面顯示的內(nèi)容是與界面綁定的埂软,當彈出框已經(jīng)彈出,但是因為某些原因后面的控制器發(fā)生了跳轉(zhuǎn)纫事,那么就會導致彈出框內(nèi)容與界面顯示發(fā)生錯誤勘畔,如果我們將彈出框彈在控制器的view上所灸,那么又會導致導航欄遮蓋不住的問題。其實炫七,我們可以通過將此彈出框設計成單例來解決這個問題爬立,如果在彈出框顯示的時候界面發(fā)生變化,我們可以通過單例方法很快捷的定位到彈窗万哪,并更新他的視圖顯示侠驯。
????????如有不足之處,歡迎提出奕巍。
? ? ? ? demo地址:https://github.com/sweetWine/DynamicAlertView