天天看點

iOS自定義alertView,繼承自UIView

自定義alertView,繼承自UIView,可以在消息區域添加子視圖:addCustomerSubview

标題可以有圖檔+文字構成, 隻支援兩個按鈕操作

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

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

CustomAlertView *alertView = [[CustomAlertView alloc] initWithTitle:@

"提示"

message:@

"dylan_lwb_"

delegate:self

cancelButtonTitle:@

"确定"

otherButtonTitles: nil];

//    [alertView addCustomerSubview:myView];

[alertView show];

[alertView release];

// - 代理方法

-(

void

)alertView:(CustomAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

{

}

-(

void

)alertViewClosed:(CustomAlertView *)alertView

{

}

-(

void

)willPresentCustomAlertView:(UIView *)alertView

{

}

// - 在項目裡建立一個CustomAlertView分類, 把下邊代碼全部複制過去, 不要管幹嘛的

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

#

if

defined(__APPLE_CC__) && (__APPLE_CC__ >=

5549

)

#define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel(

,

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

</mbalertviewdelegate></nsobject></uikit></foundation>

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429

#

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(

,

, 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(

,

, 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(

,

, 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(

,

, mWidth, mHeaderHeight)];

titleView.backgroundColor = RGBA_COLOR(

36

,

193

,

64

,

1

);

CGSize titleSize = CGSizeZero;

if

(self.title && [self.title length] >

)

{

titleSize = [self.title sizeWithFont:[UIFont fontWithName:@

"Helvetica-Bold"

size:

18

.0f]];

}

if

(titleSize.width >

)

{

// - 标題圖檔

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,

, 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(

, mHeaderHeight, mWidth, (mHeight-mHeaderHeight *

2

))];

// - 設定背景顔色

msgView.backgroundColor = [UIColor whiteColor];

// - 内容

CGSize messageSize = CGSizeZero;

if

(self.message && [self.message length]>

)

{

messageSize = [self.message sizeWithFont:[UIFont systemFontOfSize:

16

.0f] constrainedToSize:CGSizeMake(mWidth-

20

, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];

if

(messageSize.width >

)

{

UILabel *msgLabel = [[UILabel alloc] init];

msgLabel.font = [UIFont systemFontOfSize:

16

.0f];

msgLabel.text = self.message;

msgLabel.numberOfLines   =

;

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(

,

, 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(

,

, 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] >

)

{

CGFloat startY =

;

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(

, mHeaderHeight, mWidth, startY);

}

[_backView addSubview:msgView];

_backView.frame = CGRectMake(

,

, mWidth, msgView.frame.size.height + mHeaderHeight *

2

+

20

);

}

[msgView release];

// - 設定按鈕顯示區域

if

(_otherButtonTitles != nil || _cancelButtonTitle != nil)

{

UIView *btnView = [[UIView alloc] initWithFrame:CGRectMake(

, _backView.frame.size.height-mHeaderHeight, mWidth, mHeaderHeight)];

// - 如果隻顯示一個按鈕,需要計算按鈕的顯示大小

if

(_otherButtonTitles == nil || _cancelButtonTitle == nil)

{

UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake((_backView.frame.size.width-mBtnWidth) / 

2

,

, 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:

] forState:UIControlStateNormal];

}

btn.tag =

;

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,

, 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:

] forState:UIControlStateNormal];

otherBtn.layer.cornerRadius =

5

;

[otherBtn addTarget:self action:

@selector

(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

otherBtn.tag =

;

[btnView addSubview:otherBtn];

[otherBtn release];

startX += mBtnWidth+

20

;

// - 設定取消按鈕的相關屬性

UIButton *cancelBtn = [[UIButton alloc]initWithFrame:CGRectMake(startX,

, 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