First look at the Demo renderings:
This mask is often used as a newbie guide page. Usually there is a hollow part with a description to guide the user how to operate the interface for the first time, which is only displayed once.
Two implementation ideas are given below:
The first one: The UI cuts the entire picture and displays it directly on the UIWindow. This method is not recommended.
Advantages: Program implementation is simple and convenient.
Disadvantages: Multiple sets of pictures are required to adapt to different models (Android is broken inwardly), and pictures need to be updated for later iterative interface changes, and the UI workload is huge.
The second: The method used by Demo, implement a UIView by yourself, and realize the hollow area by setting the mask property of its layer.
Advantages: The UI only provides the described pictures, which reduces the application size and flexibly adapts to different models.
Disadvantages: The code is slightly more than the first, and the control frame needs to be updated for later iteration interface changes.
Paste the core code below:
Controller, ViewController:
#import "ViewController.h" #import "HWGuidePageManager.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; // create control [self creatControl]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // bootstrap view [self showGuidePage]; } - (void) creatControl { // basemap UIImageView *imgView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds]; imgView.image = [UIImage imageNamed:@"backImg"]; imgView.contentMode = UIViewContentModeScaleAspectFill; [self.view addSubview:imgView]; } - (void)showGuidePage { // Determine if it has been displayed if (![[NSUserDefaults standardUserDefaults] boolForKey:HWGuidePageHomeKey]) { // show [[HWGuidePageManager shareManager] showGuidePageWithType:HWGuidePageTypeHome completion:^{ [[HWGuidePageManager shareManager] showGuidePageWithType:HWGuidePageTypeMajor]; }]; } } @end
Encapsulated guide page management class, HWGuidePageManager.h:
#import <Foundation/Foundation.h> typedef void(^FinishBlock)(void); typedef NS_ENUM(NSInteger, HWGuidePageType) { HWGuidePageTypeHome = 0, HWGuidePageTypeMajor, }; @interface HWGuidePageManager : NSObject // get the singleton + (instancetype)shareManager; /** display method @param type guide page type */ - (void)showGuidePageWithType:(HWGuidePageType)type; /** display method @param type guide page type @param completion callback when completed */ - (void)showGuidePageWithType:(HWGuidePageType)type completion:(FinishBlock)completion; @end
HWGuidePageManager.m:
#import "HWGuidePageManager.h" @interface HWGuidePageManager () @property (nonatomic, copy) FinishBlock finish; @property (nonatomic, copy) NSString *guidePageKey; @property (nonatomic, assign) HWGuidePageType guidePageType; @end @implementation HWGuidePageManager + (instancetype)shareManager { static HWGuidePageManager *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; }); return instance; } - (void)showGuidePageWithType:(HWGuidePageType)type { [self creatControlWithType:type completion:NULL]; } - (void)showGuidePageWithType:(HWGuidePageType)type completion:(FinishBlock)completion { [self creatControlWithType:type completion:completion]; } - (void)creatControlWithType:(HWGuidePageType)type completion:(FinishBlock)completion { _finish = completion; // cover the view CGRect frame = [UIScreen mainScreen].bounds; UIView *bgView = [[UIView alloc] initWithFrame:frame]; bgView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7f]; [bgView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]]; [[UIApplication sharedApplication].keyWindow addSubview:bgView]; // info prompt view UIImageView *imgView = [[UIImageView alloc] init]; [bgView addSubview:imgView]; // first path UIBezierPath *path = [UIBezierPath bezierPathWithRect:frame]; switch (type) { case HWGuidePageTypeHome: // next path, circle [path appendPath:[UIBezierPath bezierPathWithArcCenter:KSuitPoint(227, 188) radius:KSuitFloat(46) startAngle:0 endAngle:2 * M_PI clockwise:NO]]; imgView.frame = KSuitRect(220, 40, 100, 100); imgView.image = [UIImage imageNamed:@"hi"]; _guidePageKey = HWGuidePageHomeKey; break; case HWGuidePageTypeMajor: // next path, rectangle [path appendPath:[[UIBezierPath bezierPathWithRoundedRect:KSuitRect(5, 436, 90, 40) cornerRadius:5] bezierPathByReversingPath]]; imgView.frame = KSuitRect(100, 320, 120, 120); imgView.image = [UIImage imageNamed:@"ly"]; _guidePageKey = HWGuidePageMajorKey; break; default: break; } // draw transparent area CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = path.CGPath; [bgView.layer setMask:shapeLayer]; } - (void)tap:(UITapGestureRecognizer *)recognizer { UIView *bgView = recognizer.view; [bgView removeFromSuperview]; [bgView removeGestureRecognizer:recognizer]; [[bgView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; bgView = nil; [[NSUserDefaults standardUserDefaults] setBool:YES forKey:_guidePageKey]; if (_finish) _finish(); } @end
The Demo is uploading, and it will be updated here after completion. If you need it urgently, you can leave your email.
The original intention of blogging is to hope that everyone can communicate and grow together. The limited level of bloggers is inevitably biased. Criticisms and corrections are welcome.