`

iOS 自定义UIActionSheet

 
阅读更多

 

一:模态视图

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方法添加定制的视图。


 

分享到:
评论
1 楼 静夜一曲 2013-01-17  
很好很强大!

相关推荐

    IOS自定义UIActionSheet的Demo

    本Demo旨在教你如何在iOS应用中实现自定义UIActionSheet,以提供更加灵活的交互和视觉效果。 首先,我们需要了解UIActionSheet的基本用法。UIActionSheet属于UIKit框架,通过`UIActionSheet`类来创建和管理。它包含...

    ios-自定义UIActionSheet.zip

    本资源"ios-自定义UIActionSheet.zip"提供了一个简单的自定义UIActionSheet的例子,主要探讨了如何在项目中实现更加个性化和功能丰富的弹出视图。 首先,我们了解下UIActionSheet的基本用法。UIActionSheet是...

    iOS 自定义弹出菜单 UIMenuBar.zip

    iOS 自定义弹出菜单 UIMenuBar ,UIMenuBar 是一个 iOS 自定义弹出菜单,用于替换内置的 UIActionSheet,支持...

    iOS自定义UIAlertController

    在iOS开发中,UIAlertController是苹果提供的一种用于展示警告或者动作表单的系统组件,它替代了之前的UIAlertView和UIActionSheet。然而,系统的UIAlertController在默认情况下,其Title、Message和UIAlertAction的...

    iOS模仿系统UIActionSheet,自定义弹框

    本文将详细讲解如何模仿iOS系统UIActionSheet,创建一个可自定义字体大小和颜色的弹框。 首先,我们需要了解UIActionSheet的基本用法。UIActionSheet是一个UIViewController的子类,它包含一系列的按钮,用户点击...

    自定义UIActionSheet控件功能

    自定义UIActionSheet控件功能,源码WCActionSheet,WCActionSheet 是一款自定义UIActionSheet控件 比UIActionSheet更加优雅 支持block语法,该案例控件希望可以帮到学习的朋友。 UIActionSheet is great... unless ...

    iOS开发 自定义actionSheet控件

    在iOS应用开发中,UIActionSheet是苹果提供的一种标准组件,用于展示用户可以选择的多个操作。然而,系统默认的UIActionSheet可能无法满足所有设计需求,因此开发者有时会选择自定义actionSheet控件来实现更个性化的...

    ios-自定义底部弹出视图.zip

    UIAlertController是iOS 8引入的一个新类,用于替代UIAlertView和UIActionSheet。它提供了一个更强大、更灵活的接口,可以创建包含多个按钮和输入字段的对话框。UIAlertControllerStyleActionSheet是其样式之一,...

    ios-自定义AlertView和ActionSheet.zip

    在iOS 5及以后的版本中,Apple提供了内置的UIAlertView和UIActionSheet类来实现这些功能。然而,为了满足更个性化的需求,开发者有时会选择自定义AlertView和ActionSheet。"ios-自定义AlertView和ActionSheet.zip"这...

    ios-自定义弹出视图输入框.zip

    2. **UIAlertController**:随着iOS 8的推出,苹果引入了UIAlertController,它取代了UIAlertView和UIActionSheet,并提供了更多的自定义能力,包括添加文本字段以获取用户输入。但是,UIAlertController的样式比较...

    安卓IOS风格相关-模仿IOS里面的UIActionSheet控件.rar

    1. **自定义对话框(Custom Dialog)**:Android没有直接对应的UIActionSheet控件,但可以通过自定义DialogFragment或AlertDialog来模拟相似的外观和行为。 2. **布局设计**:使用XML布局文件创建包含多个按钮的视图...

    实现类似iOS中的UIActionSheet效果

    总的来说,自定义UIActionSheet效果需要对iOS的UI编程有深入理解,包括视图层次、动画、事件处理等。通过这种方式,开发者可以自由定制UIActionSheet的外观和行为,使其更符合项目需求。在实际项目中,这样的自定义...

    ios-自定义的带有动画效果的AlertView.zip

    在iOS中,弹出视图一般指的是临时出现在屏幕上的小型视图,如UIAlertController、UIActionSheet或自定义的视图。它们通常用于通知用户或者请求用户的确认。自定义的AlertView可以更好地适应应用的设计风格,提供更...

    ios应用源码之自定义action sheet效果库 20181210

    Action Sheet在iOS中的标准实现是UIActionSheet类,但在iOS 8之后,Apple推荐使用UIAlertController替代。UIAlertController可以创建包括Action Sheet在内的多种对话框样式。然而,为了满足特定的设计需求或兼容性...

    IOS应用源码之自定义action sheet效果库 .rar

    首先,Action Sheet在iOS SDK中是UIActionSheet类,但在iOS 8之后,Apple引入了新的UIKit Dynamics,UIActionSheet被UIAlertController取代,提供了更多的定制性。UIAlertController允许开发者自定义标题、消息、...

    IOS应用源码——UIActionSheet 的美化效果.zip

    在iOS开发中,UIActionSheet是苹果提供...总之,这个源码示例是iOS开发者学习自定义UIActionSheet的一个宝贵资源,通过研究它,你可以掌握如何在不破坏系统一致性的同时,为用户提供更美观、更符合应用特色的操作提示。

    UIActionSheet

    在iOS开发中,UIActionSheet是苹果提供的一个控件,用于在用户界面中展示一系列可选操作,通常出现在屏幕底部或底部弹出。这个控件是UIKit框架的一部分,主要用于处理用户的交互事件,尤其是在移动设备上提供一种...

    自定义IOS alert

    在iOS开发中,自定义`alert`是一种常见的需求,它能提供更加丰富的用户交互体验,同时也能更好地符合应用的设计风格。本项目针对系统的`UIAlertController`进行了封装,以实现一个可高度定制且仿原生的`alert`弹框,...

    TOActionSheet:针对iOS的UIActionSheet控件的自定义设计的重新实现

    TOActionSheet TOActionSheet是一个iOS UI控件,提供了一个模式提示控件,类似于UIActionSheet 。 与UIActionSheet不同,它可以非常重地主题化,并通过为每个按钮使用块来避免委托模型。产品特点预定义的浅色和深色...

    IOS应用源码——UIActionSheet 的美化效果.rar

    这个压缩包“IOS应用源码——UIActionSheet 的美化效果.rar”显然是一个关于如何自定义和美化UIActionSheet的示例代码。在iOS开发中,尽管UIActionSheet已经提供了基本的样式,但有时开发者可能希望它更加符合应用...

Global site tag (gtag.js) - Google Analytics