图片选取按钮同样继承UIButton类,主要通过iOS系统自带的类UIImagePickerController来实现从特定源中选择图片,这里的源可能是你的手机相册,也可能是照相机。本文将介绍如何实现PickImageButton自定义类,其功能是在选取图像之后立刻按规定尺寸显示在按钮界面中,进行开发时仅需设置好一个对象属性的值,即可使用。



----------------------------------------------------------------------------------我是分割线------------------------------------------------------------------------------


效果图


ios自定义照片选择器 苹果组件自选照片_#pragma


----------------------------------------------------------------------------------干货看这里------------------------------------------------------------------------------



1. 创建PickImageButton类


  • 打开Xcode,创建一个新的工程,在工程里新建一个类,取名PickImageButton,继承UIButton,使用ARC。
  • 打开PickImageButton.h文件,编写代码如下:

#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>

@interface GYCPickImageButton : UIButton

@property (nonatomic, copy) NSString *title;
@property (nonatomic, weak) UIViewController *controller;

@property (nonatomic, strong) UIActionSheet *sheet;
@property (nonatomic, strong) UIAlertView *alert;

/**
 *  初始化PickImageButton
 *
 *  @param frame      结构
 *  @param title      标题
 *  @param controller 所属控制器
 *
 *  @return PickImageButton实例
 */
- (instancetype)initWithFrame:(CGRect)frame Title:(NSString *)title Controller:(UIViewController *)controller;

@end





  • 再在PickImageButton.m文件顶部添加如下代码,该类遵循UIActionSheetDelegate、UIAlertViewDelegate是为了处理操作表单和警告视图中特定的点击事件,由于要用到UIImagePickerController类,必须也要同时遵循UIImagePickerControllerDelegate和UINavigationControllerDelegate协议。

@interface GYCPickImageButton () <UIActionSheetDelegate, UIAlertViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
    UIImage *pickedImage;
}

@end





2. 实现功能


  • 设置默认情况下出现的操作表单(按下按钮之后)及警告视图(访问相册或打开相机时出错)
- (void)setupDefaultSheet {
    self.sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"拍照", @"从相册选取", nil];
}

- (void)setupDefaultAlert {
    self.alert = [[UIAlertView alloc] initWithTitle:@"出错" message:@"设备不支持" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
}



  • 添加按钮事件
- (void)clickedToPickImage {
    if (nil == self.sheet) {
        [self setupDefaultSheet];
    }
    [self.sheet showInView:[UIApplication sharedApplication].keyWindow];
}



  • 实现图片选取方法,这里只是创建并配置一个图像选取器,使用传入的sourceType来确定应该显示照相机还是媒体库。
- (void)pickImageFromSource:(UIImagePickerControllerSourceType)sourceType
{
    NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType];
    if ([UIImagePickerController isSourceTypeAvailable:sourceType] && [mediaTypes count] > 0) {
        NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType];
        UIImagePickerController *picker = [[UIImagePickerController alloc] init];
        picker.mediaTypes = mediaTypes;
        picker.delegate = self;
        picker.allowsEditing = YES;
        picker.sourceType = sourceType;
        [self.controller presentViewController:picker animated:YES completion:^{
            // 开始选取
        }];
    } else {
        if (nil == self.alert) {
            [self setupDefaultAlert];
        }
        [self.alert show];
    }
}



  • 接下来就是实现操作表单、警告视图和选取器视图的委托方法了:
#pragma mark - action sheet delegate

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    switch (buttonIndex) {
        // 拍照
        case 0:
            [self pickImageFromSource:UIImagePickerControllerSourceTypeCamera];
            break;
            
        // 从相册选取
        case 1:
            [self pickImageFromSource:UIImagePickerControllerSourceTypePhotoLibrary];
            break;
            
        // 取消
        case 2:
            break;
            
        default:
            break;
    }
}

#pragma mark - alert view delegate

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    
}

#pragma mark - image picker controller delegate

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *chooseMediaType = info[UIImagePickerControllerMediaType];
    if ([chooseMediaType isEqual:(NSString *)kUTTypeImage]) {
        // 如果选取图片
        pickedImage = info[UIImagePickerControllerEditedImage];
        [self setImage:pickedImage forState:UIControlStateNormal];
        [self setTitle:nil forState:UIControlStateNormal];
    }
    else if ([chooseMediaType isEqual:(NSString *)kUTTypeMovie]) {
        // 如果选取视频
        if (nil == self.alert) {
            [self setupDefaultAlert];
        }
        [self.alert show];
    }
    
    [picker dismissViewControllerAnimated:YES completion:^{
        // 取消选取之后
    }];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [picker dismissViewControllerAnimated:YES completion:^{
        // 取消选取之后
    }];
}



第三个委托方法检查用户是否选中了一张照片或视频,如果选择的是照片就将选中的照片传给之前声明的pickedImage变量,如果选择的是视频则出现警告,然后解除图像选取器的模态显示。



  • 最后实现类的初始化方法,代码如下:



- (instancetype)initWithFrame:(CGRect)frame Title:(NSString *)title Controller:(UIViewController *)controller {
    self = [super initWithFrame:frame];
    if (self) {
        self.title = title;
        self.controller = controller;
        
        [self setup];
    }
    
    return self;
}

- (void)awakeFromNib {
    self.title = self.titleLabel.text;
    [self setup];
}

- (void)setup {
    [self setTitle:self.title forState:UIControlStateNormal];
    [self addTarget:self action:@selector(clickedToPickImage) forControlEvents:UIControlEventTouchUpInside];
}





3. 运行调试


  • 创建一个新的视图控制器类



ios自定义照片选择器 苹果组件自选照片_#pragma_02



  • 点击PickImageButtonViewController.xib文件,打开Interface Builder,在对象库选择Button然后拖拽到主视图区域,对其进行如下编辑:


ios自定义照片选择器 苹果组件自选照片_ios自定义照片选择器_03



  • 修改Class为PickImageButton:


ios自定义照片选择器 苹果组件自选照片_控件_04



  • 添加输出口:
@property (weak, nonatomic) IBOutlet GYCPickImageButton *button1;


  • 在PickImageButtonViewController.m文件的viewDidLoad方法中添加以下代码:
//使用xib
    self.button1.controller = self;
    
    //使用initWithFrame
    PickImageButton *button2 = [[PickImageButton alloc] initWithFrame:CGRectMake(0, 0, 120, 120) Title:@"上传头像" Controller:self];
    button2.center = CGPointMake(CGRectGetMidX(self.view.bounds), 320);
    [button2 setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
    [button2 setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
    [button2 setTitleColor:[UIColor lightGrayColor] forState:UIControlStateSelected];
    [self.view addSubview:button2];




最后在AppDelegate.m文件中设置根视图为PickImageButtonViewController即可编译运行。



----------------------------------------------------------------------------------我是分割线------------------------------------------------------------------------------




就是这么简单,在此基础上读者还可以扩展其他的一些功能,如对拍摄的图像和选取的照片进行裁剪这样简单的编辑。


完!