------------- 基本思路 --------------
- 搭建界面,九宮格算法
- 處理按鈕選中狀態(tài)
- 按鈕之間畫線
- 手指和按鈕之間畫線
- 判斷解鎖密碼是否正確
------------- 基本思路 --------------
- 判斷解鎖密碼是否正確
拖拽圖片素材
設(shè)置控制器 view 的背景色為"HomeButtomBG"圖片平鋪后的效果
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"HomeButtomBG"]];在控制器中拖拽一個(gè) UIView, 設(shè)置寬高都是300, 并設(shè)置約束(在父容器中水平、垂直居中對(duì)齊)。
自定義一個(gè) view, 設(shè)置這個(gè)自定義 view 與界面上的 view 相關(guān)聯(lián)
在自定義 view 中添加一個(gè) buttons 屬性, 在懶加載中生成9個(gè) UIButton, 并且把這寫 Button 都添加到 view 中。
- 創(chuàng)建每個(gè) UIButton
- 設(shè)置每個(gè) UIButton的默認(rèn)情況下的背景圖片、 selected 下的背景圖片、disabled 下的背景圖片
在 layoutSubviews 方法中根據(jù)九宮格的方式計(jì)算每個(gè)按鈕的 frame
實(shí)現(xiàn)觸摸到某個(gè)按鈕的時(shí)候, 讓這個(gè)按鈕的狀態(tài)變成 selected
7.1 在自定義 view 的 touchesBegan:方法中根據(jù)當(dāng)前的觸摸點(diǎn), 判斷是否觸碰到了某個(gè)按鈕
- 設(shè)置這個(gè)按鈕的 selected狀態(tài)
- 把這個(gè)按鈕記錄下來(lái)(添加到 selectedButtons 集合中)
7.2 在自定義 view 的 touchesMoved:方法中根據(jù)當(dāng)前的觸摸點(diǎn), 判斷是否觸碰到了某個(gè)按鈕
- 設(shè)置這個(gè)按鈕的 selected狀態(tài)
- 把這個(gè)按鈕記錄下來(lái)(添加到 selectedButtons 集合中), 同時(shí)要判斷這個(gè)按鈕是否已經(jīng)是 selected = YES了, 避免重復(fù)添加。
- 同時(shí)記錄下本次觸摸的 point到 currentPoint屬性中。
** 注意: 此處必須設(shè)置按鈕禁止與用戶交互(btn.userInteractionEnabled = NO;), 否者手指觸摸到按鈕上以后, 按鈕會(huì)捕獲這個(gè)觸摸事件, 就不會(huì)觸發(fā) view的 touchesBegan:事件了。
- 在 drawRect:方法中繪制線條
- 判斷如果 self.selectedButtons長(zhǎng)度為0, 那么直接返回不需要繪制任何內(nèi)容
- 如果 self.selectedButtons長(zhǎng)度不為0:
1> 循環(huán) self.selectedButtons集合中的每個(gè)按鈕
2> 判斷如果是第一個(gè)按鈕那么移動(dòng)到起點(diǎn)(起點(diǎn)為第一個(gè)按鈕的 center point)
3> 如果不是第一個(gè)按鈕那么直接添加線段到這個(gè)按鈕的 center point
4> 繪制完畢按鈕以后, 最后再添加一條線段到 currentPoint。
// 線條的顏色
#define SteveZLineColor [UIColor colorWithRed:0.0 green:170/255.0 blue:255/255.0 alpha:1.0]
/**
錯(cuò)誤:
<Error>: void CGPathAddLineToPoint(CGMutablePathRef, const CGAffineTransform *, CGFloat, CGFloat): no current point.
原因:
在第一次繪圖的時(shí)候 path 對(duì)象中沒(méi)有任何點(diǎn)
解決:(判斷如果沒(méi)有需要繪制的按鈕, 那么就直接返回)
if (self.selectedButtons.count == 0) {
return;
}
*/
在touchesEnded:方法中, 將所有按鈕的 selected 狀態(tài)設(shè)置為 NO, 清空 self.selectedButtons 集合, 重新繪制。
為每個(gè)按鈕添加一個(gè) tag, 用來(lái)判斷手勢(shì)解鎖是否正確
- 通過(guò)代理把解鎖的密碼傳遞給控制器, 在控制器中判斷解鎖是否正確, 如果正確代理方法返回 YES, 否則返回 NO
- 在定義 view 中, 根據(jù)代理方法返回的結(jié)果判斷如果 YES, 那么直接執(zhí)行第9步
- 如果返回為 NO:
1> 先將 self.selectedButtons中的所有按鈕selected狀態(tài)設(shè)置為 NO, enabled 也設(shè)置為 NO
2> 在把線條顏色設(shè)置為紅色
3> 執(zhí)行重繪
4> 0.5秒鐘之后, 在執(zhí)行第9步。
- 細(xì)節(jié)處理
- 透明問(wèn)題
1> 如果是完全通過(guò)代碼創(chuàng)建 UIView, 在繪圖的時(shí)候, 如果指定了控件的透明(opaque = NO)opaque 表示不透明, 那么在繪圖時(shí)會(huì)有問(wèn)題。
2> 如果希望是透明, 那么要把顏色指定為 clearColor, 而不是 opaque = NO