iOS開發- 自訂遮罩視圖(引導, 功能說明)源碼+解析

來源:互聯網
上載者:User

iOS開發- 自訂遮罩視圖(引導, 功能說明)源碼+解析
iOS開發- 自訂遮罩視圖(引導, 功能說明)源碼+解析

我們平時使用App的時候, 經常在第一次使用的時候, 會有類似”新手教程”之類的東西, 來引導我們應該如何使用這個App。

但是這個”新手教程”不同於常規的引導頁(引導頁指第一次開啟App時候, 彈出的那種介紹視圖。 他是靜態, 不需要與使用者互動, 可以直接一頁頁翻, 或者直接跳過。)所謂的”新手教程”, 就是按照App的提示, 一步步跟著完成。

那這個“新手教程”有什麼好處呢?

指導使用者瞭解操作。 比如, 如何調節音量, 如何設定焦距… 限制使用者填充必要資訊, 完成必要操作。

現在大家應該都明白這到底是一個什麼東西了。為實現這樣的功能, 一般是採用遮罩層效果, 今天花了點時間, 封裝好了這樣一個功能。 同時把源碼分享到我的Github, 需要的可以自己下載。

下載連結: YLZHoledView

同時, 還寫了一個demo, 效果如下:
 

我封裝好的這個檔案(YLZHoledView), 主要實現了如下功能:
1. 添加多種樣式聚光燈效果。(圓形, 矩形, 圓角矩形, 自訂視圖)
2. 點擊該地區支援delegate回調
3. UIView 中的控制項事件穿透。(demo中的按鈕, 是在遮罩層下方, 但是正確響應點擊事件, 這就是事件穿透)

好了, 大體介紹就到這裡, 下面簡單解釋下核心代碼:

delegate回調

YLZHoledView.h

@class YLZHoledView;@protocol YLZHoledViewDelegate - (void)holedView:(YLZHoledView *)holedView didSelectHoleAtIndex:(NSUInteger)index;@end

YLZHoledView.m

#pragma mark - Tap Gesture - (void)tapGestureDetectedForGesture:(UITapGestureRecognizer *)gesture {     if ([self.holeViewDelegate respondsToSelector:@selector(holedView:didSelectHoleAtIndex:)]) {         CGPoint touchLocation = [gesture locationInView:self];         [self.holeViewDelegate holedView:self didSelectHoleAtIndex:[self holeViewIndexForAtPoint:touchLocation]];     } }

這裡先在自訂的View中添加手勢, 然後在
- (NSUInteger)holeViewIndexForAtPoint:(CGPoint)touchLocation 中判斷點擊範圍是否屬於遮罩層中添加的視圖, 再發送委託。

然後在我們的實作類別中, 也就是實現這個委託的地方, 就可以通過index來做相關的操作。 我demo裡面只是簡單的列印。

聚光燈效果

我這裡封裝了幾種常見的類型。(圓形, 矩形, 圓角矩形, 自訂視圖)

typedef NS_ENUM(NSInteger, YLZHoleType) {     YLZHoleTypeCirle,     YLZHoleTypeRect,     YLZHoleTypeRoundedRect,     YLZHoleTypeCustomRect };

然後重寫
- (void)drawRect:(CGRect)rect
通過類型判斷, 來重寫對應的效果。

比如, 圓形的代碼:

if (hole.holeType == YLZHoleTypeRoundedRect) {             YLZRoundedRectHole *rectHole = (YLZRoundedRectHole *)hole;             CGRect holeRectIntersection = CGRectIntersection( rectHole.holeRect, self.frame);             UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:holeRectIntersection                                                                   cornerRadius:rectHole.holeCornerRadius];             CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), [[UIColor clearColor] CGColor]);             CGContextAddPath(UIGraphicsGetCurrentContext(), bezierPath.CGPath);             CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);             CGContextFillPath(UIGraphicsGetCurrentContext());}
事件穿透

在這之前, 提一個方法。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
// recursively calls -pointInside:withEvent:. point is in the receiver’s coordinate system

只要實現了最頂層的 UIView 的 hitTest 方法,在某些情況返回下層的某個按鈕執行個體,即相當於把那個按鈕的事件透出來了,比如在點擊落在該按鈕上時,不管這個按鈕在 UIView 下多少層都可以把它挖出來。

所以, 重寫hitTest方法即可。

 #pragma mark - UIView Overrides  - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {     UIView *hitView = [super hitTest:point withEvent:event];     if (hitView == self)     {         for (UIView *focus in self.focusView) {             if (CGRectContainsPoint(focus.frame, point))             {                 return focus;             }         }     }     return hitView; }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.