图片选取按钮同样继承UIButton类,主要通过iOS系统自带的类UIImagePickerController来实现从特定源中选择图片,这里的源可能是你的手机相册,也可能是照相机。本文将介绍如何实现PickImageButton自定义类,其功能是在选取图像之后立刻按规定尺寸显示在按钮界面中,进行开发时仅需设置好一个对象属性的值,即可使用。
----------------------------------------------------------------------------------我是分割线------------------------------------------------------------------------------
效果图
----------------------------------------------------------------------------------干货看这里------------------------------------------------------------------------------
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. 运行调试
- 创建一个新的视图控制器类
- 点击PickImageButtonViewController.xib文件,打开Interface Builder,在对象库选择Button然后拖拽到主视图区域,对其进行如下编辑:
- 修改Class为PickImageButton:
- 添加输出口:
@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即可编译运行。
----------------------------------------------------------------------------------我是分割线------------------------------------------------------------------------------
就是这么简单,在此基础上读者还可以扩展其他的一些功能,如对拍摄的图像和选取的照片进行裁剪这样简单的编辑。
完!