gestureLock(手勢(shì)鎖)實(shí)現(xiàn)步驟
- 布局控件:背景控件和手勢(shì)鎖控件
- 手勢(shì)鎖控件:
- 子控件:循環(huán)增加9個(gè)按鈕,設(shè)置屬性(注意是選中狀態(tài)不是高亮狀態(tài)),根據(jù)九宮格布局位置
- 選中實(shí)現(xiàn):按鈕的選中通過哪種方法都會(huì)有高亮狀態(tài)的延遲,所以我們不讓按鈕與用戶交互,而是通過觸摸事件(touchesBegan和touchesMove),pointInside WithEvent 逐次判斷點(diǎn)是否落在按鈕上,若是,則選中并加入選中按鈕數(shù)組,否則不選中。另外已經(jīng)選中的不重復(fù)選中
- 將按鈕中心點(diǎn)連線:在drawRect中將按鈕用線段連接起來
- 將按鈕與當(dāng)前點(diǎn)連線:在touchesMove方法中,記錄當(dāng)前點(diǎn)的位置,要求重繪,在drawRect中,從最后一個(gè)點(diǎn)畫出一條線到當(dāng)前點(diǎn)
- 保存密碼及清空?qǐng)D案:松開手時(shí),由于要記錄密碼,所以應(yīng)該在創(chuàng)建按鈕時(shí)綁定tag值,最后遍歷數(shù)組,拼接字符串將密碼保存下來;取消按鈕選中,將選中按鈕數(shù)組清空,重繪。
涂鴉畫板實(shí)現(xiàn)步驟

涂鴉畫板.png
- 布局控件(做好屏幕適配):上面的工具欄(通過toolBar布局),下面的繪圖工具欄(IOS9之后可以用Stack View布局,IOS9之前就拖3個(gè)按鈕,做好屏幕適配),中間的畫板(繼承UIView)
-
畫板畫線功能:
- 通過手勢(shì)來監(jiān)聽移動(dòng),
開始監(jiān)聽時(shí)創(chuàng)建path,設(shè)置線寬,并加入到paths(因?yàn)橐嫸鄠€(gè)圖形)
- 手勢(shì)改變時(shí),畫線,由于是要將多個(gè)點(diǎn)連接起來,所以要記錄下
當(dāng)前的path,不斷的在self.path中畫線,重繪 - 拼接路徑可以不在drawRect中,但渲染必須在,因?yàn)橐@示在layer上下文中
- drawRect中,要將paths中的path逐一畫出來
- 通過手勢(shì)來監(jiān)聽移動(dòng),
-
繪圖工具欄:監(jiān)聽滑條欄和按鈕,根據(jù)view.h提供的線寬和顏色,設(shè)置線寬和顏色。
- 這里要注意,如果重繪時(shí)要將所有顏色畫出來,必須寫path的分類,增加顏色屬性;在drawRect方法中,調(diào)用【path.color set】,將線段畫出來;線寬不用的原因是,系統(tǒng)提供的path屬性自帶線寬
-
在vc.m中,拖線監(jiān)聽功能實(shí)現(xiàn)。為了封裝性,里面的實(shí)現(xiàn)的功能應(yīng)該調(diào)用view.h提供的方法
- 清除功能:將paths數(shù)組清空,重繪
- 撤銷功能:將最后一個(gè)path從數(shù)組中移除,重繪
- 橡皮擦功能:設(shè)置path的顏色為白色
- 保存功能:開啟位圖上下文,將layer圖層通過renderInContext渲染到當(dāng)前上下文中(即位圖上下文),從圖層中獲取圖片,保存到系統(tǒng)相冊(cè)中
- 照片功能:到系統(tǒng)相冊(cè)中選擇圖片,通過modal跳轉(zhuǎn),選擇完后回到畫板,顯出選擇的圖片,需要進(jìn)行處理(示例中缺少提示,應(yīng)該增加蒙板提示)
- 處理圖片功能:從相冊(cè)中返回的圖片
- 傳遞給一個(gè)繼承自UIView的處理圖片類(里面有一個(gè)圖片子控件,使得處理后的圖片通過drawInRect方法繪制到畫板時(shí)能跟處理時(shí)一樣。若是直接用imageView處理,最后傳回畫板時(shí),圖片會(huì)被放大至全屏)
- 增加手勢(shì)進(jìn)行調(diào)整,最后長(zhǎng)按時(shí),圖片實(shí)現(xiàn)閃爍(通過動(dòng)畫設(shè)置透明度),通過位圖上下文取出圖片,通過通知返回處理后的圖片,畫到畫板上;將圖片加到paths數(shù)組中,在drawRect中,由于圖片不能通過描線畫出,要用
[path isKindOfClass:[UIImage class]]判斷,如果是圖片,就[image drawInRect:rect]畫出圖片
保存功能
// 渲染圖層
[_drawView.layer renderInContext:UIGraphicsGetCurrentContext()];
// 保存圖片到系統(tǒng)相冊(cè)里
// image:保存的圖片
// completionTarget:保存完成的監(jiān)聽者
// completionSelector:保存完成的時(shí)候調(diào)用監(jiān)聽者的方法,該方法不能隨便調(diào)用
//核心代碼
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
//
}
// 保存圖片完成的時(shí)候必須調(diào)用下面方法
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
if (error) {
[MBProgressHUD showError:@"保存失敗"];
}else{
[MBProgressHUD showSuccess:@"保存成功"];
}
}
照片功能
// 選擇照片
- (IBAction)pickerPhoto:(id)sender {
// 進(jìn)入系統(tǒng)的相冊(cè)UIImagePickerController
// 創(chuàng)建一個(gè)照片選擇控制器
UIImagePickerController *imagePickerVc = [[UIImagePickerController alloc] init];
// 設(shè)置數(shù)據(jù)源
imagePickerVc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
// 設(shè)置代理
imagePickerVc.delegate = self;
// modal
[self presentViewController:imagePickerVc animated:YES completion:nil];
}
#pragma mark - UIImagePickerControllerDelegate
// 用戶選擇照片的時(shí)候調(diào)用
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// 獲取用戶選擇照片
UIImage *image = info[UIImagePickerControllerOriginalImage];
[self dismissViewControllerAnimated:YES completion:nil];
// 處理下圖片
// 創(chuàng)建處理圖片的view
HandleImageView *hanldImageV = [[HandleImageView alloc] initWithFrame:_drawView.frame];
[self.view addSubview:hanldImageV];
// 給處理圖片的view傳遞圖片
hanldImageV.image = image;
}