【转载】iOS 自定义UIActionSheet
【转自】http://o0o0o0o.iteye.com/blog/1749756
一:模态视图
UIActionSheet、UIAlertView、GKPeerPickerController、UIAPopover、GKPanel等都是ios系统自带
的模态视图。
模态视图的一个重要的特性就是在显示模态视图的时候可以阻断其他视图的事件响应。
该特性在有些时候对我们是非常有用的。
那么任何自己实现一个模态视图呢?
一种方式就是自己实现一个UIViewController,然后作为一个modalViewController视图显示。这种方式固然可以
,但是需要的工作量可就不少了,例如显示动画,动态布局等等。
这里我要说的另一种方法,就是实现这些系统模态视图的子视图,对系统视图进行定制,以满足我们自己的需求。可以完美的使用系统模态
视图已经提供的动画、自动布局等等行为。
二:系统模态视图的显示方式
系统模态视图的显示和上面提到到的自定义模态视图的显示方式有很大的差别。
UIActionSheet、UIAlertView、GKPeerPickerController、UIAPopover、GKPanel 都是UIView的子类,
如果直接在读取视图之上显示这些UIActionSheet等等的视图,是无法阻断事件的。因此系统自带的这些模态
视图先被添加到一个UIWindow的视图,再把给window视图作为application的keyWindow显示。也就是在显示
模态视图的时候,application的多window的。
三:移除系统模态
调用dismiss系列的方法移除模态视图
四:模态视图的实现基础
所有的模态视图都基于UIViewControll提供的两个方法:
– presentModalViewController:animated:
– dismissModalViewControllerAnimated:
UIActionSheet、UIAlertView的实现都是对这两个方法的实现和在实现。
五:向模态视图添加其他UIView的方式:
一:动态添加UIView
(1):通过[UIApplication sharedApplication].keyWindow 取得当前的makeKeyAndVisible window,该window的
大小是这个屏幕的大小,和该window包含的 UIActionSheet等视图不是一个级别。UIActionSheet 仅仅是该window的
一个子视图而已。
[[UIApplication sharedApplication].keyWindow addSubview:self.progressHUD];
(2):根据读取模态视图的window属性,取得当前的makeKeyAndVisible window
[self.actionSheet.window addSubview:self.progressHUD]
注意:以上两种方式一定要在模态视图显示出来之后再添加其他的UIview,否则添加的UIView可能无法显示。
二:静态添加UIView
把需要添加的UIView视图直接在模态视图的drawRect方法中添加就可以了。这些在显示模态视图时候,添加的
UIView也会被显示处理。
UIActionSheet 视图的自定义
- //
- // UserDetailVoiceCustomActionSheet.h
- // BaiHe
- //
- // Created by xu on 12-12-15.
- // Copyright (c) 2012年 itotemstudio. All rights reserved.
- //
- #import <UIKit/UIKit.h>
- @protocol BHCustomActionSheetDelegate <NSObject>
- @optional
- - (void)actionSheet:(UIActionSheet *)actionSheet clickedOtherButtonAtIndex:(NSInteger)buttonIndex;
- - (void)actionSheetCancel:(UIActionSheet *)actionSheet;
- - (void)actionSheetDestructive:(UIActionSheet *)actionSheet;
- @end
- @interface BHCustomActionSheet : UIActionSheet
- {
- UIButton *_destructiveButton;
- id<BHCustomActionSheetDelegate> _customActionDelegate;
- }
- @property (nonatomic, retain) UIButton *destructiveButton;
- @property (nonatomic, assign) id<BHCustomActionSheetDelegate> customActionDelegate;
- @end
- //
- // UserDetailVoiceCustomActionSheet.m
- // BaiHe
- //
- // Created by xu on 12-12-15.
- // Copyright (c) 2012年 itotemstudio. All rights reserved.
- //
- #import "BHCustomActionSheet.h"
- #import "UIImageExt.h"
- @interface BHCustomActionSheet ()
- - (void)clickedOtherButton:(id)sender;
- - (void)clickCanncelButton;
- - (void)clickDestructiveButton;
- @end
- @implementation BHCustomActionSheet
- @synthesize destructiveButton = _destructiveButton;
- @synthesize customActionDelegate = _customActionDelegate;
- - (void)dealloc
- {
- _customActionDelegate = nil;
- RELEASE_SAFELY(_destructiveButton);
- [super dealloc];
- }
- //去除背景色
- - (void)drawRect:(CGRect)rect
- {
- UIImageView *bgView = [[[UIImageView alloc] initWithFrame:self.bounds] autorelease];
- bgView.image = [[UIImage imageNamed:@"bg"] resizeUsingCapInsets:UIEdgeInsetsMake(180.f, 5.f, 4.f, 4.f)];
- [self addSubview:bgView];
- UILabel *titleLabel = nil;
- NSMutableArray *buttons = [NSMutableArray arrayWithCapacity:10];
- for (UIView *view in self.subviews) {
- if ([view isKindOfClass:[UIControl class]]) {
- [self bringSubviewToFront:view];
- [buttons addObject:view];
- [view removeFromSuperview];
- }
- if ([view isKindOfClass:[UILabel class]]) {
- titleLabel = (UILabel *)view;
- }
- }
- // if (titleLabel) {
- CGRect hilghtBgImageFrame = CGRectMake(0.0f, 0.0f, CGRectGetWidth(rect), CGRectGetMaxY(titleLabel.frame) == 0.f?60.f:CGRectGetMaxY(titleLabel.frame) + 5.f);
- UIImageView *hilghtBgImageView = [[[UIImageView alloc] initWithFrame:hilghtBgImageFrame] autorelease];
- [self addSubview:hilghtBgImageView];
- [self bringSubviewToFront:titleLabel];
- hilghtBgImageView.image = [[UIImage imageNamed:@"bg-highlight"] resizeUsingCapInsets:UIEdgeInsetsMake(31.f, 5.f, 42.f, 4.f)];
- // }
- NSMutableIndexSet *delSet = [NSMutableIndexSet indexSet];
- if (self.destructiveButtonIndex >= 0) {
- NSString *destructiveButtonTitle = [self buttonTitleAtIndex:self.destructiveButtonIndex];
- UIButton *customDestructiveBut = [UIButton buttonWithType:UIButtonTypeCustom];
- self.destructiveButton = customDestructiveBut;
- [customDestructiveBut setTitleColor:[UIColor whiteColor]
- forState:UIControlStateNormal];
- [customDestructiveBut setTitleShadowColor:[UIColor whiteColor]
- forState:UIControlStateNormal];
- customDestructiveBut.titleLabel.font = [UIFont boldSystemFontOfSize:18.f];
- [customDestructiveBut setBackgroundImage:[[UIImage imageNamed:@"but_Destructive"] resizeUsingCapInsets:UIEdgeInsetsMake(15.f, 50., 20.f, 60.f)]
- forState:UIControlStateNormal];
- [customDestructiveBut addTarget:self
- action:@selector(clickDestructiveButton)
- forControlEvents:UIControlEventTouchUpInside];
- customDestructiveBut.frame = ((UIControl *)[buttons objectAtIndex:self.destructiveButtonIndex]).frame;
- [customDestructiveBut setTitle:destructiveButtonTitle forState:UIControlStateNormal];
- [self addSubview:customDestructiveBut];
- [delSet addIndex:self.destructiveButtonIndex];
- }
- if (self.cancelButtonIndex >= 0) {
- NSString *cancelButtonTitle = [self buttonTitleAtIndex:self.cancelButtonIndex];
- UIButton *customCancelBut = [UIButton buttonWithType:UIButtonTypeCustom];
- [customCancelBut setTitleColor:[UIColor grayColor]
- forState:UIControlStateNormal];
- [customCancelBut setTitleShadowColor:[UIColor grayColor]
- forState:UIControlStateNormal];
- customCancelBut.titleLabel.font = [UIFont boldSystemFontOfSize:18.f];
- [customCancelBut setBackgroundImage:[[UIImage imageNamed:@"but_Cancel"] resizeUsingCapInsets:UIEdgeInsetsMake(15.f, 50., 20.f, 60.f)]
- forState:UIControlStateNormal];
- [customCancelBut addTarget:self
- action:@selector(clickCanncelButton)
- forControlEvents:UIControlEventTouchUpInside];
- customCancelBut.frame = ((UIControl *)[buttons objectAtIndex:self.cancelButtonIndex]).frame;
- [customCancelBut setTitle:cancelButtonTitle forState:UIControlStateNormal];
- [self addSubview:customCancelBut];
- [delSet addIndex:self.cancelButtonIndex];
- }
- [buttons removeObjectsAtIndexes:delSet];
- int index = 0;
- for (UIControl *control in buttons) {
- NSString *otherButtonTitle = [self buttonTitleAtIndex:index];
- UIButton *customOtherBut = [UIButton buttonWithType:UIButtonTypeCustom];
- [customOtherBut setTitleColor:[UIColor grayColor]
- forState:UIControlStateNormal];
- [customOtherBut setTitleShadowColor:[UIColor grayColor]
- forState:UIControlStateNormal];
- customOtherBut.titleLabel.font = [UIFont boldSystemFontOfSize:18.f];
- [customOtherBut setBackgroundImage:[[UIImage imageNamed:@"but_Cancel"] resizeUsingCapInsets:UIEdgeInsetsMake(15.f, 50., 20.f, 60.f)]
- forState:UIControlStateNormal];
- customOtherBut.tag = index;
- [customOtherBut addTarget:self
- action:@selector(clickedOtherButton:)
- forControlEvents:UIControlEventTouchUpInside];
- customOtherBut.frame = ((UIControl *)[buttons objectAtIndex:index]).frame;
- [customOtherBut setTitle:otherButtonTitle forState:UIControlStateNormal];
- [self addSubview:customOtherBut];
- index ++;
- }
- [buttons removeAllObjects];
- }
- #pragma mark - Private Method
- - (void)clickedOtherButton:(id)sender
- {
- NSInteger index = ((UIControl *)sender).tag;
- if (self.customActionDelegate
- && [self.customActionDelegate respondsToSelector:@selector(actionSheet:clickedButtonAtIndex:)]) {
- [self.customActionDelegate actionSheet:self clickedOtherButtonAtIndex:index];
- }
- [self clickCanncelButton];
- }
- - (void)clickCanncelButton
- {
- if (self.customActionDelegate
- && [self.customActionDelegate respondsToSelector:@selector(actionSheetCancel:)]) {
- [self.customActionDelegate actionSheetCancel:self];
- }
- [UIApplication sharedApplication].statusBarHidden = NO;
- }
- - (void)clickDestructiveButton
- {
- if (self.customActionDelegate
- && [self.customActionDelegate respondsToSelector:@selector(actionSheetDestructive:)]) {
- [self.customActionDelegate actionSheetDestructive:self];
- }
- }
- @end
重新drawRect方法,可以去除UIActionSheet的默认样式,然后通过addSubView方法添加定制的视图。