在日常開(kāi)發(fā)中有時(shí)候我們需要在APP中做用戶(hù)指導(dǎo),比如第一次進(jìn)入某個(gè)頁(yè)面的時(shí)候顯示遮罩覆蓋, 但是又需要將遮罩下的某些區(qū)域暴露出來(lái),便于文字說(shuō)明,比如我們需要在視圖上加個(gè)遮罩,并且遮罩上要顯示 按鈕2 :

原圖
期待的效果圖:按鈕1被蓋住,而 按鈕2顯示出來(lái)

效果
我們可以 在視圖上加個(gè)遮罩,再往遮罩上畫(huà)一個(gè)同樣位置和樣式的 按鈕2 ,作為一個(gè)有追求的程序猿,我們是不能容忍這種 低效實(shí)現(xiàn)方式的。
我們可以通過(guò)iOS 的 Core Graphics 來(lái)實(shí)現(xiàn),也很簡(jiǎn)單,只需要兩句代碼
重寫(xiě) 遮罩視圖里面的 draw 方法:
override func draw(_ rect: CGRect) {
//利用 UIBezierPath 繪制出 按鈕2 的外觀路徑,
let path = UIBezierPath.init(roundedRect: CGRect.init(x: 100, y: 300, width: 100.0, height: 40.0), cornerRadius: 20.0)
//設(shè)置 路徑填充樣式為 clear 清除樣式, 就能 使設(shè)置的路徑中的 繪圖區(qū)域被擦除掉
path.fill(with: .clear, alpha: 0.1)
}
點(diǎn)擊穿透:
如果我們需要在遮罩上點(diǎn)擊按鈕2 區(qū)域響應(yīng) 按鈕2的事件,點(diǎn)擊其它區(qū)域響應(yīng)遮罩上的點(diǎn)擊事件,我們可以重寫(xiě) 遮罩上的 事件傳遞方法hitTest:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
//按鈕2區(qū)域的路徑
let path = UIBezierPath.init(roundedRect: CGRect.init(x: 100, y: 300, width: 100.0, height: 40.0), cornerRadius: 20.0)
//判斷 點(diǎn)擊事件在 按鈕2區(qū)域則 返回nil
if path.contains(point) {
return nil
}else{
return super.hitTest(point, with: event)
}
}