随着业务的拓展,以及代码的整合,发现最初的那一坨简单选择系统相册和拍照选择一张图片跟换一个头像的鸡肋功能占用了控制器大量的代码,以及稍微业务逻辑复杂的VC就更加显得臃肿而不容易阅读与以及管理,
以前在知乎上曾听人吹嘘说超过500行的VC将不再容易维护,所以才会出现MVVM以及MVP之流的,将以前在控制器写的一些代码分割到各自管理类,Model以及ViewModel中处理数据以及业务逻辑相关的东西,至于MVP的 Presents也和ViewModel类似都不过是MVC模式的衍生版本,为的是解耦,以及Model和View的复用,提升开发效率,体量不大的小公司也许对于这种类似模块化开发的模式优势并不明显,但是这种开发思想值得深入研究,有利于拓宽开发思路和技术实现手段. 从今天就要开始写一写,记录一下自己的开发岁月啦哈哈哈哈哈哈哈哈😁
关于MVC
MVC: 在model里发起网络请求,将回调的结果交给控制器, 控制器将数
据传递给View层,view层根据数据展现出不同的形态, 用户的行为操
作,view层监听触摸事件,反馈到控制器,控制器操作model进行网络请求,
请求到数据再回调给控制器这样子的一个来回,View和model之间是没
有直接来往的…(自己通俗的理解需要华丽的辞藻来修饰润色~)
数据model: 负责业务逻辑处理,封装数据,存储数据,处理数据运算等工作.
负责主要的数据或者操作数据的数据访问层
视图View:
负责展示,监听用户操作事件等工作
主要负责展示层
控制器ViewController:
负责处理model与View的交互关系, 事件响应、数据加工等工作
关于MVVM
MVVM(Model View ViewModel)是一种基于MVC和MVP的架构模式,
它试图将用户界面(UI)从业务逻辑和行为中更加清晰地分离出来。
个人理解是和传统的MVC原理是一致的,只是将View和Model交互这块
代码移交给了ViewModel这个类来进行管理, view和model不会有直接
的联系,是通过viewMode使两者进行数据的传输与通过数据对UI的渲
染,实际上控制器Controller已经成为了一个View的作用,相当于一个大
容器Vew.
关乎MVP
这种模式也是从MVC衍生出来的,它的View和Model和MVC一样,只是多
了一个中间层,处理View和Model的一个东西叫Presenters,他持有View
的对象和Model的数据对象,在它这里提供一个平台让View和Model肆无
忌惮的PY交易,就是这个么个道理。然后View和Model互不影响,还可以
复用,只进入身体,不进入生活哈哈哈哈哈 我编不下去了....
[PS.]吹过牛逼之后,言归正传,切入正题,做个笔记,仅此而已,作为一个程序员负责单纯就好了,不要耍什么心机什么阴谋阳谋诡计心眼,玩不过人家专门搞这些职场勾心斗角的....谈个恋爱也是不要让寄几太累,该吃吃该喝喝该玩玩,接不接盘也无所谓,当然是选择原谅她啦,然后婚后孩子还不一定是亲生的~ .... 求证隔壁老王内心OS , 自行脑补简直炸裂不忍卒视....
推荐一个好玩到流鼻血的游戏 --- Forgive all over the world 原谅全世界
========================
WGBSystemImagePickerManager.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <MediaPlayer/MediaPlayer.h>
@interface WGBSystemImagePickerManager : NSObject
/// 创建这样一个管理类对象
- (instancetype)initWithViewController:(UIViewController *)VC;
///选择图片的回调block
@property (nonatomic,copy) void(^didSelectImageBlock) (UIImage *image);
/// 相册选择器对象
@property (nonatomic,strong) UIImagePickerController *imagePicker;
///最大视频时长
@property (nonatomic,assign) NSTimeInterval videoMaximumDuration;
@property (nonatomic,assign) BOOL isVideo;
#pragma mark- 快速创建一个图片选择弹出窗
- (void)quickAlertSheetPickerImage ;
#pragma mark- 打开相机
- (void)openCamera;
#pragma mark- 打开相册
- (void)openPhoto ;
@end
========================
WGBSystemImagePickerManager.m
#import "WGBSystemImagePickerManager.h"
@interface WGBSystemImagePickerManager ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIActionSheetDelegate>
///来源控制器
@property (nonatomic,strong) UIViewController *orginViewController;
/// 取出的图片
@property (nonatomic,strong) UIImage *tempImage;
@end
@implementation WGBSystemImagePickerManager
- (UIImagePickerController *)imagePicker{
if (!_imagePicker) {
_imagePicker = [[UIImagePickerController alloc] init];
_imagePicker.delegate = self;
/// 转场动画方式
// _imagePicker.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
_imagePicker.allowsEditing = YES; //允许编辑
_imagePicker.videoMaximumDuration = 15 ; //视频时长默认15s
_imagePicker.videoQuality = UIImagePickerControllerQualityTypeHigh;
}
return _imagePicker;
}
- (void)setIsVideo:(BOOL)isVideo{
_isVideo = isVideo;
if (isVideo == YES) {
/// 媒体类型
_imagePicker.mediaTypes = @[(NSString *)kUTTypeImage,(NSString *)kUTTypeMovie];
}else{
/// 媒体类型
_imagePicker.mediaTypes = @[(NSString *)kUTTypeImage];
}
}
- (instancetype)initWithViewController:(UIViewController *)VC{
self = [super init];
if (self) {
self.orginViewController = VC;
}
return self;
}
#pragma mark- 快速创建一个图片选择弹出窗
- (void)quickAlertSheetPickerImage{
UIActionSheet *sheetView = [[UIActionSheet alloc] initWithTitle:@"选择图片" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"相册",@"拍照", nil];
[sheetView showInView:self.orginViewController.view];
}
#pragma mark-<UIActionSheetDelegate>
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(@"---%ld",buttonIndex);
if (buttonIndex == 0) {
///相册
[self openPhoto];
}else if (buttonIndex == 1){
/// 拍照
[self openCamera];
}
}
#pragma mark- 打开相机
- (void)openCamera{
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
return ;
}
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self.orginViewController presentViewController: self.imagePicker animated:YES completion:^{
NSLog(@"相机");
}];
}
#pragma mark- 打开相册
- (void)openPhoto{
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
return ;
}
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self.orginViewController presentViewController: self.imagePicker animated:YES completion:^{
NSLog(@"相册");
}];
}
#pragma mark- <UIImagePickerControllerDelegate>
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
UIImage *orginImage = info[UIImagePickerControllerOriginalImage];
self.tempImage = [self fixOrientation: orginImage];
/// 选择的图片
if(self.didSelectImageBlock){
self.didSelectImageBlock(self.tempImage);
}
///拍到的照片顺带保存到相册
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
[self saveImageToSystemPhotosAlbum];
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark- 拍的照片保存到系统相册
- (void)saveImageToSystemPhotosAlbum{
UIImageWriteToSavedPhotosAlbum(self.tempImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
/// 系统指定的回调方法
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
NSString *msg = nil ;
if(error != NULL){
msg = @"保存图片失败" ;
}else{
msg = @"保存图片成功" ;
}
NSLog(@"%@",msg);
// UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:msg preferredStyle:UIAlertControllerStyleAlert];
// [[UIApplication sharedApplication].keyWindow.rootViewController showViewController:alert sender:nil];
}
///矫正图片方向
- (UIImage*)fixOrientation:(UIImage*)aImage
{
// No-op if the orientation is already correct
if (aImage.imageOrientation == UIImageOrientationUp)
return aImage;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (aImage.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
default:
break;
}
switch (aImage.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
default:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
CGImageGetBitsPerComponent(aImage.CGImage), 0,
CGImageGetColorSpace(aImage.CGImage),
CGImageGetBitmapInfo(aImage.CGImage));
CGContextConcatCTM(ctx, transform);
switch (aImage.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.height, aImage.size.width), aImage.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0, 0, aImage.size.width, aImage.size.height), aImage.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage* img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
@end
简单功能简单封装,简单使用,用完即走
控制器代码调用,一句代码搞定
#import "ViewController.h"
#import "WGBSystemImagePickerManager.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic,strong) WGBSystemImagePickerManager *manager;
@end
@implementation ViewController
- (WGBSystemImagePickerManager *)manager{
if (!_manager) {
_manager = [[WGBSystemImagePickerManager alloc] initWithViewController:self];
}
return _manager;
}
- (void)viewDidLoad {
[super viewDidLoad];
__weak typeof(self) weakSelf = self;
[self.manager setDidSelectImageBlock:^(UIImage *img){
weakSelf.imageView.image = img;
}];
}
- (IBAction)clickAction:(UISegmentedControl *)sender {
switch (sender.selectedSegmentIndex) {
case 0:
{
///相册
[self.manager openPhoto];
}
break;
case 1:
{
///相机
[self.manager openCamera];
}
break;
case 2:
{
}
break;
case 3:
{
[self.manager quickAlertSheetPickerImage];
}
break;
default:
break;
}
}
@end