一:效果如圖:
二:代碼
#import "ViewController.h" #import "DrawView.h" #import "HandleImageView.h" @interface ViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate,handleImageViewDelegate> @property (weak, nonatomic) IBOutlet DrawView *drawView; @end @implementation ViewController /** * 1:屬於誰的東西,應該在誰里面去寫,盡量減少控制器中的代碼。因為設置的都在self.drawView上進行繪制的 * */ //清屏 - (IBAction)clear:(id)sender { [self.drawView clear]; } //撤銷 - (IBAction)undo:(id)sender { [self.drawView undo]; } //橡皮擦 - (IBAction)erase:(id)sender { [self.drawView erase]; } //設置線的寬度 - (IBAction)setLineWidth:(UISlider *)sender { [self.drawView setLineWith:sender.value]; } //設置線的顏色 /** *sender.backgroundColor:調用的btn的get方法獲得是背景色,點擊不同的按鈕,將不同按鈕的背景色傳遞給self.drawView */ - (IBAction)setLineColor:(UIButton *)sender { [self.drawView setLineColor:sender.backgroundColor]; } /** * 1:UIImagePickerController:能更改中文,但是需要遵守UINavigationControllerDelegate,UIImagePickerControllerDelegate兩個協議,可以指定sourceType,delegate,presentViewController彈出,在代理可以根據sourceType類型做判斷,必須手動去dissmiss * */ //照片 - (IBAction)photo:(id)sender { //從系統相冊當中選擇一張圖片 //1.彈出系統相冊 UIImagePickerController *pickerVC = [[UIImagePickerController alloc] init]; //設置照片的來源 pickerVC.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; pickerVC.delegate = self; //modal出系統相冊 [self presentViewController:pickerVC animated:YES completion:nil]; } /** * 1: 不用ImageView的原因是,ImageView經過手勢縮放等處理后,不知道了其實際的尺寸,所以用UIView中放UImageView,上下文的大小就為UIView大小 2:要想保存圖片,先要生成圖片,開啟上下文,將drawView的layer繪制到上下文中(將UIView繪制到drawView的上下文中),得到圖片之后UIImageWriteToSavedPhotosAlbum,寫入系統的相冊,注意:@selector里面的方法不能夠瞎寫,必須得是image:didFinishSavingWithError:contextInfo: * */ //保存 - (IBAction)save:(id)sender { //把繪制的東西保存到系統相冊當中 //1.開啟一個位圖上下文 UIGraphicsBeginImageContextWithOptions(self.drawView.bounds.size, NO, 0); //2.把畫板上的內容渲染到上下文當中 CGContextRef ctx = UIGraphicsGetCurrentContext(); [self.drawView.layer renderInContext:ctx]; //3.從上下文當中取出一張圖片 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); //4.關閉上下文 UIGraphicsEndImageContext(); //5.把圖片保存到系統相冊當中 //注意:@selector里面的方法不能夠瞎寫,必須得是image:didFinishSavingWithError:contextInfo: UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } //保存完畢時調用 - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { NSLog(@"success"); } //- (void)saveSuccess { // NSLog(@"success"); //} - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark -- 隱藏狀態欄 - (BOOL)prefersStatusBarHidden { return YES; } /** *1:打印info信息:通過key值獲取image,將image轉化成二進制流的NSData形式,UIImagePNGRepresentation,UIImageJPEGRepresentation,兩種轉化方式,png保持原圖不壓縮,內存大,JPEG可以限制壓縮系數,越大圖片越不清晰,轉化成NSData,writeToFile寫入桌面 2:先用一個UIView,添加到self.view上,UIView再添加UIImageView,再將整個View的layer繪制到上下文中,UIView設置成透明色,則UIView下面的路徑就會顯示出來了 * */ //當選擇某一個照片時,會調用這個方法 -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info { NSLog(@"%@",info); UIImage *image = info[UIImagePickerControllerOriginalImage]; //NSData *data = UIImageJPEGRepresentation(image, 1); NSData *data = UIImagePNGRepresentation(image); //[data writeToFile:@"/Users/xiaomage/Desktop/photo.jpg" atomically:YES]; [data writeToFile:@"/Users/xiaomage/Desktop/photo.png" atomically:YES]; HandleImageView *handleV = [[HandleImageView alloc] init]; handleV.backgroundColor = [UIColor clearColor]; handleV.frame = self.drawView.frame; handleV.image = image; handleV.delegate = self; [self.view addSubview:handleV]; //self.drawView.image = image; //取消彈出的系統相冊 [self dismissViewControllerAnimated:YES completion:nil]; } -(void)handleImageView:(HandleImageView *)handleImageView newImage:(UIImage *)newImage { self.drawView.image = newImage; } - (void)pan:(UIPanGestureRecognizer *)pan { CGPoint transP = [pan translationInView:pan.view]; pan.view.transform = CGAffineTransformTranslate(pan.view.transform, transP.x, transP.y); //復位 [pan setTranslation:CGPointZero inView:pan.view]; } /** * 初始界面的搭建: 1:狀態欄的改變:1:全局狀態欄的設定,配合pilist中設置viewcontrollerbase 設置其值為no 2:在控制器中實現方法,prefersStatusBarHidden,和狀態欄樣式的方法 2:界面的搭建:在搭建控制器或是view的界面的時候:1:先分析界面的UI結構由哪些控件組成,采用分層封裝的思想,將控制器或是view的零散控件封裝在一個整體的模塊中(xib也類似),如何分層?參考新浪微博cell的分層封裝,如何封裝view,參考view的封裝方法.2:若是項目中都會用到這些模塊,就想到抽成父類,讓子類去繼承,不同的部分分別在子類中實現,若是父類想和子類進行關聯,則父類提供方法供子類去重寫,則父類也可以拿到該值。 3:1:對於頂部的UI,可以采用view封裝,但是要考慮橫屏豎屏的適配,很麻煩,所以可以用toolBar控件,里面自動適配toolBar中的按鈕,拖一個toolBar,往里面添加toolBaritem,保存按鈕的添加,就添加一個彈簧,還可以對彈簧進行設置,就會出現上圖的效果。2:底部UI的構建:1:三個按鈕橫屏豎屏的適配,先設置左側按鈕左間距底部間距,右側間距,中間按鈕右側間距底部間距,最右側按鈕右側間距底部間距,三個按鈕等寬,則可以實現三個按鈕平分屏幕的寬度,在設置按鈕的高度,slider設置,左右頂部高度,大view不用設置高度了,其高度會等於所有子控件的高度之和。2:ios9新出來一個控件,StackView,可以解決三個按鈕的適配,直接將按鈕拖進去,設置間距就可以了,自動適配 2:在拖線設置的時候,按住shift鍵,再拖線同時設置多個間距 */ @end
#import <UIKit/UIKit.h> @interface DrawView : UIView //清屏 - (void)clear; //撤銷 - (void)undo; //橡皮擦 - (void)erase; //設置線的寬度 - (void)setLineWith:(CGFloat)lineWidth; //設置線的顏色 - (void)setLineColor:(UIColor *)color; /** 要繪制的圖片 */ @property (nonatomic, strong) UIImage * image; @end
#import "DrawView.h" #import "MyBezierPath.h" @interface DrawView() /** 當前繪制的路徑 */ @property (nonatomic, strong) UIBezierPath *path; //保存當前繪制的所有路徑 @property (nonatomic, strong) NSMutableArray *allPathArray; //當前路徑的線寬 @property (nonatomic, assign) CGFloat width; //當前路徑的顏色 @property (nonatomic, strong) UIColor *color; @end @implementation DrawView - (NSMutableArray *)allPathArray { if (_allPathArray == nil) { _allPathArray = [NSMutableArray array]; } return _allPathArray; } /** * 1:一般一次性設置的內容都放在初始化方法init中或是awakefromNib中 2:添加拖拽pan手勢用於繪圖 */ - (void)awakeFromNib { //添加手勢 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [self addGestureRecognizer:pan]; self.width = 1; self.color = [UIColor blackColor]; } -(void)setImage:(UIImage *)image { _image = image; //添加圖片添加到數組當中 [self.allPathArray addObject:image]; //重繪 [self setNeedsDisplay]; } /** * 3:方法的封裝,一般我們在控制器寫代碼的時候,遇到的業務邏輯要想到去封裝,盡量減少控制器的代碼,封裝的代碼和誰有關系就封裝到哪里:1:能分類封裝就分類封裝,減少類的創建,節省空間,一個參數則可以直接選類方法,兩個參數建議使用對象方法,在分類中屬性定義某個變量,不會生成下划線的成員變量,需要自己重寫set'方法和get方法,才能獲得或是修改變量,若是在普通類中用readonly修飾,則在本類中可以調用get方法,但是不能使用set方法,可以使用下划線的成員變量,但是子類繼承父類后,不能繼承帶下划線的成員變量,不能調用set,只能調用get 2:封裝成工具類:單例或是類方法,若是單例,則盡量將方法抽成屬性,通過重寫封裝 ,類方法,想獲得單一一樣的成員變量則可以static定義全局或是局部變量。3:繼承:把相同的部分都封裝在父類中,不同的部分讓子類去單獨實現,若是父類想和子類進行數據溝通,則父類可以提供方法,供子類去重寫 4:三種方法封裝的主要思想就是:將與外界無關的邏輯全部封裝在類的內部,類在提供接口供外界訪問,讓外界調用是最簡潔的 * */ /** *清屏:清屏就是要移除所有的路徑,此時刪除大數組中的所有的路徑就可以,在調用setNeedsDisplay,進行重繪,此時數組中沒有了任何一條路徑,所以就會清空上下文 */ //清屏 - (void)clear { //清空所有的路徑 [self.allPathArray removeAllObjects]; //重繪 [self setNeedsDisplay]; } /** *撤銷:即是取出路徑數組中的最后一個路徑刪除,並調用setNeedsDisplay */ //撤銷 - (void)undo { //刪除最后一個路徑 [self.allPathArray removeLastObject]; //重繪 [self setNeedsDisplay]; } /** * 橡皮擦功能就是:又繪制了一條路徑,只是設置路徑的顏色為白色,將其他顏色的路徑覆蓋掉 */ //橡皮擦 - (void)erase { [self setLineColor:[UIColor whiteColor]]; } //設置線的寬度 - (void)setLineWith:(CGFloat)lineWidth { self.width = lineWidth; } //設置線的顏色 /** * 設置線的顏色,應該考慮到當沒有設置顏色的時候,或傳入的參數為空值的時候,所以要考慮以上兩點,所以要設置線的默認顏色,一次性設置,在init或是awakefromNib中去設置 * * @param color */ - (void)setLineColor:(UIColor *)color { self.color = color; } #pragma mark -- drawview的pan拖拽手勢,畫線 /** *2:在拖拽手勢方法中:1:繪制UIBezierPath路徑:開始設置起點,change的時候添加聯系,並調用setNeedsDisplay,異步調用drawRect方法 2:定義一個全局數組,用於保存所有的路徑,最后需要遍歷數組,將所有路徑取出來,繪制到上下文中 3:只有在自定義view中才能重寫drawRect方法,且drawRect方法配合setNeedsDisplay使用,此方法必須由系統調用才會生成與view相關聯的上下文,其中路徑可以在其他方法中繪制,但是最后將路徑繪制到上下文中的時候就必須在drawRect方法中實現[phath stroke];或是[path fill]; 2:什么情況下自定義類或是控件:1:當發現系統原始的功能,沒有辦法瞞足自己需求時,這個時候,要自定義類.繼承系統原來的東西.再去添加屬性自己的東西. 2:在begin方法中每次都創建一個全新的路徑,因為在一次繪制的時候begin方法只執行一次,將每一次創建的路徑都保存在大數組中,在drawrect中遍歷,得到路徑去繪制。其中顏色的繪制必須在drawrect上下文中繪制,否則不會顯示,因為路徑path沒有保存color,但是線寬有保存,所以自定義類MyBezierPath繼承UIBezierPath,提供color屬性,就是為了保存color,在draw遍歷時取出path后,直接設置路徑顏色。 */ - (void)pan:(UIPanGestureRecognizer *)pan { //獲取的當前手指的點 CGPoint curP = [pan locationInView:self]; //判斷手勢的狀態 if(pan.state == UIGestureRecognizerStateBegan) { //創建路徑 //UIBezierPath *path = [UIBezierPath bezierPath]; MyBezierPath *path = [[MyBezierPath alloc] init]; self.path = path; //設置起點 [path moveToPoint:curP]; //設置線的寬度 [path setLineWidth:self.width]; //設置線的顏色 //什么情況下自定義類:當發現系統原始的功能,沒有辦法瞞足自己需求時,這個時候,要自定義類.繼承系統原來的東西.再去添加屬性自己的東西. path.color = self.color; [self.allPathArray addObject:path]; } else if(pan.state == UIGestureRecognizerStateChanged) { //繪制一根線到當前手指所在的點 [self.path addLineToPoint:curP]; //重繪 [self setNeedsDisplay]; } } /** * 1:當遍歷的時候,若是數組中含有的不只是同一種類型的對象,在遍歷的時候可以每個對象指定同一個類型的對象,再根據iskindofclass來判斷對象具體是那種類型。 2:當畫圖片的時候:直接用image調用[image drawInRect:rect];或是drawpoint * */ -(void)drawRect:(CGRect)rect { //繪制保存的所有路徑 for (MyBezierPath *path in self.allPathArray) { //判斷取出的路徑真實類型 if([path isKindOfClass:[UIImage class]]) { UIImage *image = (UIImage *)path; [image drawInRect:rect]; }else { [path.color set]; [path stroke]; } } } @end
#import <UIKit/UIKit.h> @interface MyBezierPath : UIBezierPath /** 當前路徑的顏色 */ @property (nonatomic, strong) UIColor *color; @end
#import "MyBezierPath.h" @implementation MyBezierPath @end
#import <UIKit/UIKit.h> @class HandleImageView; @protocol handleImageViewDelegate <NSObject> - (void)handleImageView:(HandleImageView *)handleImageView newImage:(UIImage *)newImage; @end @interface HandleImageView : UIView /** <#注釋#> */ @property (nonatomic, strong) UIImage *image; /** <#注釋#> */ @property (nonatomic, weak) id<handleImageViewDelegate> delegate; @end
#import "HandleImageView.h" @interface HandleImageView()<UIGestureRecognizerDelegate> /** 在UIView上添加一張 UIImageView */ @property (nonatomic, weak) UIImageView *imageV; @end @implementation HandleImageView /** *1: 懶加載UIImageView,屬性修飾也可以用weak修飾,能用weak的時候盡量用weak,其中_imageV = imageV賦值的時候既可以寫在添加[self addSubview:imageV];之前也可以寫在其之后 * * @return UIImageView */ -(UIImageView *)imageV { if (_imageV == nil) { UIImageView *imageV = [[UIImageView alloc] init]; imageV.frame = self.bounds; imageV.userInteractionEnabled = YES; [self addSubview:imageV]; _imageV = imageV; //添加手勢 [self addGes]; } return _imageV; } -(void)setImage:(UIImage *)image { _image = image; NSLog(@"%@",self.imageV); self.imageV.image = image; } /** * 2:添加手勢:1:添加了拖拽pan,長按longpress,捏合手勢pinch,旋轉手勢:rotation.1:這些手勢都分三種狀態,開始,改變,結束,其中在使用這些手勢一直繪制的時候,開始只調用一次 2:在這些手勢中都可以獲得觸摸點,locationInView,還可以拖拽距離translationInView,點擊的view,旋轉角度,捏合比例,而且若是想相對上次改變,則一定要進行復位操作 3:若是想同時支持多個手勢,需要將添加的手勢設置手勢代理,實現otherGestureRecognizer代理方法返回YES,則這樣就可以同時支持多個手勢。一般涉及旋轉平移縮放都與transform一起用,累加形變和非累加形變。 4:復位操作:復位,只要想相對於上一次旋轉就復位 [pan setTranslation:CGPointZero inView:pan.view]; pinch.scale = 1;rotation.rotation = 0; * */ //添加手勢 -(void)addGes{ // pan // 拖拽手勢 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [self.imageV addGestureRecognizer:pan]; // pinch // 捏合 UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)]; pinch.delegate = self; [self.imageV addGestureRecognizer:pinch]; //添加旋轉 UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)]; rotation.delegate = self; [self.imageV addGestureRecognizer:rotation]; // 長按手勢 UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; [self.imageV addGestureRecognizer:longPress]; } //捏合的時候調用. - (void)pinch:(UIPinchGestureRecognizer *)pinch { pinch.view.transform = CGAffineTransformScale( pinch.view.transform, pinch.scale, pinch.scale); // 復位 pinch.scale = 1; } //旋轉的時候調用 - (void)rotation:(UIRotationGestureRecognizer *)rotation { // 旋轉圖片 rotation.view.transform = CGAffineTransformRotate(rotation.view.transform, rotation.rotation); // 復位,只要想相對於上一次旋轉就復位 rotation.rotation = 0; } //長按的時候調用 // 什么時候調用:長按的時候調用,而且只要手指不離開,拖動的時候會一直調用,手指抬起的時候也會調用 - (void)longPress:(UILongPressGestureRecognizer *)longPress { if (longPress.state == UIGestureRecognizerStateBegan) { [UIView animateWithDuration:0.25 animations:^{ //設置為透明 self.imageV.alpha = 0; }completion:^(BOOL finished) { [UIView animateWithDuration:0.25 animations:^{ self.imageV.alpha = 1; //把當前的View做一個截屏 UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0); //獲取上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); [self.layer renderInContext:ctx]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); //關閉上下文. UIGraphicsEndImageContext(); //調用代理方法 if([self.delegate respondsToSelector:@selector(handleImageView:newImage:)]) { [self.delegate handleImageView:self newImage:newImage]; } //從父控件當中移除 [self removeFromSuperview]; }]; }]; } } //拖動的時候調用 - (void)pan:(UIPanGestureRecognizer *)pan{ CGPoint transP = [pan translationInView:pan.view]; pan.view.transform = CGAffineTransformTranslate(pan.view.transform, transP.x, transP.y); //復位 [pan setTranslation:CGPointZero inView:pan.view]; } //能夠同時支持多個手勢 -(BOOL)gestureRecognizer:(nonnull UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(nonnull UIGestureRecognizer *)otherGestureRecognizer{ return YES; } @end
畫板界面分析.
頂部是一個工具欄.有清屏,撤銷,橡皮擦,照片功能.最右部是一個保存按鈕
中間部分為畫板區域
最下部拖動滑竿能夠改變畫筆的粗線.可以選顏色.
1.界面搭建
最上部為一個ToolBar,往ToolBar拖些item,使用ToolBar的好處.里面按鈕的位置不需要我們再去管理.
給最上部的工具欄做自動布局.離父控件左,上,右都為0,保存工具條的高度不度
拖一個UIView當前下部的View.在下部的View當中拖累三個按鈕,設置每一個按鈕的背景顏色.
點擊每一按鈕時辦到設置畫筆的顏色.
其中三個按鈕只間的間距始終保存等,每一個按鈕的寬度和高度都相等.通過自動布局的方式辦到.
先把這個UIView的自動布局設好, 讓其左,右,下都是0,高度固定.
自動布局設置為:第一個按鈕高度固定,與左,右,下都保存20個間距.
第二個按鈕與第一個按鈕,高度,寬度,centerY都相等.與右邊有20個間距.
第三個按鈕也是第一個按鈕的高度,寬度,centerY都相等.與右邊有20個間距,最右邊也保存20個間距.
最后是中間的畫板區域,畫板區域只需要上距離上下左右都為0即可.
2.實現畫板功能.
當手指移動的時候,在中間的畫板區域當中進行繪制.由於每一個路徑都有不同的狀態.所以我們就不能用一條路徑來做.
所以要弄一個數組記錄住每一條路徑.
實現畫板功能.
1.監聽手指在屏幕上的狀態.在開始點擊屏幕的時候,創建一個路徑.並把手指當前的點設為路徑的起點.
弄一個成員屬性記錄當前繪制的路徑.並把當前的路徑添加到路徑數組當中.
2.當手指在移動的時候,用當前的路徑添加一根線到當前手指所在的點.然后進行重繪.
3.在繪圖方法當中.取出所有的路徑.把所有的路徑給繪制出來.
3.設置路徑屬性.
提供屬性方法.
清屏功能:刪除所有路徑進行重繪
撤銷功能:刪除最后一條路徑,進行重繪
設置線寬:
由於每一條線寬度都不樣.所以要在開始創建路徑的時,就要添加一個成員屬性,設置一個默認值.
在把當前路徑添加到路徑數組之前,設置好線的寬度.然后重寫線寬屬性方法.
下一次再創建路徑時,線的寬度就是當前設置的寬度.
設置線的顏色:
同樣,由於每一條線的顏色也不一樣.也需要記錄住每一條路徑的顏色.
由於UIBezierPath沒有給我們直接提供設置顏色的屬性.我們可以自定義一個UIBezierPath.
創建一個MyBezierPath類,繼承UIBezierPath,在該類中添加一個顏色的屬性.
在創建路徑的時候,直接使用自己定義的路徑.設置路徑默認的一個顏色.方法給設置線寬一樣.
在繪圖過程中, 取出來的都是MyBezierPath,把MyBezierPath的顏色設置路徑的顏色.
橡皮擦功能:橡皮擦功能其實就是把路徑的顏色設為白色.
4.保存繪制的圖片到相冊.
保存相冊的思路:就是把繪制的在View上的內容生成一張圖片,保存到系統相冊當中.
具體步驟:
開啟一個跟View相同大小的圖片上下文.
把View的layer上面內容渲染到上下文當中.
生成一張圖片,把圖片保存到上下文.
關閉上下文.
如何把一張圖片保存到上下文?
調用方法:
參數說明:
第一個參數:要寫入到相冊的圖片.
第二個參數:哪個對象堅聽寫入完成時的狀態.
第三個參數:圖片保存完成時調用的方法
UIImageWriteToSavedPhotosAlbum(newImage,
self,
@selector(image:didFinishSavingWithError: contextInfo:),nil);
注意:圖片保存完成時調用的方法必須得是image:didFinishSavingWithError: contextInfo:
5.選擇圖片.
點擊圖片時彈出系統的相冊.
如果彈出系統的相冊?
使用UIImagePickerController控件器Modal出它來.
UIImagePickerController *pick = [[UIImagePickerController alloc] init];
設置照片的來源
pick.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
設置代碼,監聽選擇圖片,UIImagePickerController比較特殊,它需要遵守兩個協議
<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
pick.delegate = self;
modal出控件器
[self presentViewController:pick animated:YES completion:nil];
注意沒有實現代碼方法時,選擇一張照片會自動的dismiss掉相冊控制器.但是設置代碼后,就得要自己去dismiss了
實現代理方法.
選擇的照片就在這個方法第二個參數當中, 它是一個字典
-(void)imagePickerController:(nonnull UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(nonnull NSDictionary<NSString *,id> *)info{
獲取當前選中的圖片.通過UIImagePickerControllerOriginalImage就能獲取.
UIImage *image = info[UIImagePickerControllerOriginalImage];
}
獲取完圖片后.圖片是能夠縮放,平移的,因此獲取完圖片后,是在畫板板View上面添加了一個UIView.
只有UIView才能做平移,縮放,旋轉等操作.
因此做法為.在圖片選擇完畢后,添加一個和畫板View相同大小的UIView,這個UIView內部有一個UIImageView.
對這個UIImageView進行一些手勢操作.操作完成時.長按圖片,把View的內容截屏,生成一張圖片.
把新生成的圖片繪制到畫板上面.
6.繪制圖片.
在畫板View當中提供一個UImage屬性,供外界傳遞.重寫屬性的set方法,每次傳遞圖片時進行重繪
畫圖片也有有序的,所以要把圖片也添加到路徑數組當中.
在繪圖片過過程當中,如果發現取出來的是一個圖片類型.那就直接圖片繪制到上下文當中.
具體實現代碼為:
-(void)drawRect:(CGRect)rect{
for (DrawPath *path in self.pathArray) {
if ([path isKindOfClass:[UIImage class]]) {
UIImage *image = (UIImage *)path;
[image drawInRect:rect];
}else{
[path.lineColor set];
[path stroke];
}
}
}