IOS SDK详解之拍照/相册(默认+自定义拍照界面)

版权所有,禁止匿名转载;禁止商业使用。

前言:本来要更新NSURLSession的UploadTask的,结果写那个Demo的时候想要写成拍照上传,然后就想到先写一个关于拍照的Demo吧。本文会先介绍下如何使用系统提供的界面拍照和选择相册,然后自定义拍照界面。注意,本文使用的是UIImagePickerController,所以不能完全的自定义,如果想要彻底的自定义拍照,建议选择AV Foundation这个框架来做


Demo效果


进入系统的拍照界面

IOS开发,自定义拍照,拍照源码


进入自定义拍照界面

UVVRZfY.gif


自定义前置摄像头和后置摄像头切换动画-翻页

IOS开发,自定义拍照,拍照源码


一 使用系统提供的界面拍照和相册选择


第一步 

保存一个UIImagePickerController的实例,然后适当的时候初始化始化。Demo选择在viewDidLoad初始化。让当前类实现UIImagePickerControllerDelegate,UINavigationControllerDelegate两个代理


@property (strong,nonatomic)UIImagePickerController * imagePikerViewController;
//初始化
self.imagePikerViewController = [[UIImagePickerController alloc] init];
self.imagePikerViewController.delegate = self;//通过代理来传递拍照的图片
self.imagePikerViewController.allowsEditing = YES;//允许编辑

第二步,通过ActionSheet来让用户选择是拍照还是到相册选择,然后模态的显示

[self presentViewController:self.imagePikerViewController animated:YES completion:NULL];

注意,要先判断相机是否可用,然后在进入相机(有可能相机坏了,或者在虚拟机上运行的)


UIAlertController * alertController = [UIAlertController alertControllerWithTitle: nil
                                      message: nil
                                   preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction: [UIAlertAction actionWithTitle: @"Take Photo" style: UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
  if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
    self.imagePikerViewController.sourceType = UIImagePickerControllerSourceTypeCamera;
    [self presentViewController:self.imagePikerViewController animated:YES completion:NULL];
  }else{
    [self showAlertWithMessage:@"Camera is not available in this device or simulator"];
  }
}]];
[alertController addAction: [UIAlertAction actionWithTitle: @"Choose Existing Photo" style: UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
  if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){
    self.imagePikerViewController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    [self presentViewController:self.imagePikerViewController animated:YES completion:NULL];
  }
}]];
[alertController addAction: [UIAlertAction actionWithTitle: @"Cancel" style: UIAlertActionStyleCancel handler:nil]];
[self presentViewController: alertController animated: YES completion: nil];

第三部,代理函数处理拍照或者cancel事件


-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
  UIImage * image = info[UIImagePickerControllerEditedImage];
  if (!image) {
    image = info[UIImagePickerControllerOriginalImage];
  }
  self.imageview.image = image;
  [self dismissViewControllerAnimated:YES completion:NULL];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
  [self dismissViewControllerAnimated:YES completion:NULL];
}

二 自定义拍照界面


UIImagePickerController的自定义界面比较简单,通过设置cameraOverlayView这个属性为自定义的View就能自定义。


第一步 创建一个View

创建xib文件

IOS开发,自定义拍照,拍照源码


拖拽控件,进行autoLayout,最终效果如图

IOS开发,自定义拍照,拍照源码


把fileOwner设置成CustomTakePhotoViewController

IOS开发,自定义拍照,拍照源码


第二步 在显示拍照界面之前,把UI设置成自己想要的,注意,把属性 

showsCameraControls设置为NO,不让默认的界面出现。



self.imagePikerViewController.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imagePikerViewController.showsCameraControls = NO;
[[NSBundle mainBundle] loadNibNamed:@"CustomOverLayview" owner:self options:nil];
self.takePictureButton.layer.cornerRadius = 20;
self.takePictureButton.clipsToBounds = YES;
self.overlayView.frame = self.imagePikerViewController.cameraOverlayView.frame;
self.overlayView.backgroundColor = [UIColor clearColor];
self.imagePikerViewController.cameraOverlayView = self.overlayView;
self.overlayView = nil;
[self presentViewController:self.imagePikerViewController animated:YES completion:NULL];

第三步,为view上的控件添加动作

Segment Control负责切换前置摄像头和后置摄像头,为了流畅,在切换的时候显示动画。


- (IBAction)cameraSelect:(UISegmentedControl *)sender{
  NSInteger index = sender.selectedSegmentIndex;
  if (index == 0) {
    [UIView transitionWithView:self.imagePikerViewController.view duration:1.0 options:UIViewAnimationOptionAllowAnimatedContent | UIViewAnimationOptionTransitionCurlDown animations:^{
      self.imagePikerViewController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
    } completion:NULL];
  }else{
    [UIView transitionWithView:self.imagePikerViewController.view duration:1.0 options:UIViewAnimationOptionAllowAnimatedContent | UIViewAnimationOptionTransitionCurlUp animations:^{
      [self.imagePikerViewController setCameraDevice:UIImagePickerControllerCameraDeviceRear];
    } completion:NULL];
  }
}


拍照的Button


- (IBAction)takePicture:(id)sender {
    [self.imagePikerViewController takePicture];
}

取消的Button


- (IBAction)cancelTakePicture:(id)sender {
    [self dismissViewControllerAnimated:YES completion:NULL];
}

第四步 在代理中处理图片


-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
  UIImage * image = info[UIImagePickerControllerEditedImage];
  if (!image) {
    image = info[UIImagePickerControllerOriginalImage];
  }
  self.imageview.image = image;
  [self dismissViewControllerAnimated:YES completion:NULL];
}


注意,如果log输出


Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.

直接忽略就是了,没有任何影响,貌似是IOS 8的一个bug


PhotoDemo.zip


  • 分类:IOS
  • 标签:
0 0