首先看一下Demo效果图:
这种遮罩通常作为新手引导页面。通常有镂空的一部分,附有描述,指引用户第一次进入界面该如何操作,只显示一次。
下面给出两种实现思路:
第一种:UI切好整张图片,直接显示到UIWindow上,不推荐使用该方法。
优点:程序实现简单,便捷。
缺点:适配不同机型需要多套图片(Android内心是崩溃的),后期迭代界面改动则要更新图片,UI工作量庞大。
第二种:Demo使用的方法,自己实现一个UIView,通过设置其layer的mask属性来实现镂空区域。
优点:UI只提供描述的图片即可,减少应用大小,灵活适配不同机型。
缺点:代码较第一种略多,后期迭代界面改动要更新控件frame。
下面贴上核心代码:
控制器,ViewController:
#import "ViewController.h" #import "HWGuidePageManager.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; // 创建控件 [self creatControl]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // 引导视图 [self showGuidePage]; } - (void)creatControl { // 底图 UIImageView *imgView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds]; imgView.image = [UIImage imageNamed:@"backImg"]; imgView.contentMode = UIViewContentModeScaleAspectFill; [self.view addSubview:imgView]; } - (void)showGuidePage { // 判断是否已显示过 if (![[NSUserDefaults standardUserDefaults] boolForKey:HWGuidePageHomeKey]) { // 显示 [[HWGuidePageManager shareManager] showGuidePageWithType:HWGuidePageTypeHome completion:^{ [[HWGuidePageManager shareManager] showGuidePageWithType:HWGuidePageTypeMajor]; }]; } } @end
封装的指引页管理类,HWGuidePageManager.h:
#import <Foundation/Foundation.h> typedef void(^FinishBlock)(void); typedef NS_ENUM(NSInteger, HWGuidePageType) { HWGuidePageTypeHome = 0, HWGuidePageTypeMajor, }; @interface HWGuidePageManager : NSObject // 获取单例 + (instancetype)shareManager; /** 显示方法 @param type 指引页类型 */ - (void)showGuidePageWithType:(HWGuidePageType)type; /** 显示方法 @param type 指引页类型 @param completion 完成时回调 */ - (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; // 遮盖视图 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]; // 信息提示视图 UIImageView *imgView = [[UIImageView alloc] init]; [bgView addSubview:imgView]; // 第一个路径 UIBezierPath *path = [UIBezierPath bezierPathWithRect:frame]; switch (type) { case HWGuidePageTypeHome: // 下一个路径,圆形 [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: // 下一个路径,矩形 [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; } // 绘制透明区域 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
Demo正在上传,完成后会更新在这里,急要的可以留下邮箱。
写博客的初心是希望大家共同交流成长,博主水平有限难免有偏颇之处,欢迎批评指正。