本文使用了蒙版工具类SingleMaskView。

1.支持透明区自定义位置和大小,支持矩形带圆角大小和(椭)圆形;

2.支持添加多个透明区或者图片;

3.目前支持添加图片,添加label可仿照修改代码;

4.点击自动消失,也可以根据自己需求修改代码实现,比如说点击按钮(背景图片为:“知道啦”)蒙版消失。

SingleMaskView.h 代码:

#import <UIKit/UIKit.h>

@interface SingleMaskView : UIView
// 蒙版颜色(非透明区颜色,默认黑色0.5透明度)
@property (nonatomic, strong) UIColor *maskColor;

// 添加矩形透明区(位置和弧度)
- (void)addTransparentRect:(CGRect)rect withRadius:(CGFloat)radius;

// 添加圆形透明区
- (void)addTransparentOvalRect:(CGRect)rect;

// 添加图片(图片和位置)
- (void)addImage:(UIImage*)image withFrame:(CGRect)frame;

// 在指定view上显示蒙版(过渡动画)
/*
不调用用此方法可使用 addSubview:自己添加展示
*/
- (void)showMaskViewInView:(UIView *)view;

// 销毁蒙版view(默认点击空白区自动销毁)
- (void)dismissMaskView;

@end

SingleMaskView.m 代码如下:

#import <Foundation/Foundation.h>
#import "SingleMaskView.h"

@interface SingleMaskView ()

@property (nonatomic, weak) CAShapeLayer *fillLayer;
@property (nonatomic, strong) UIBezierPath *overlayPath;
@property (nonatomic, strong) NSMutableArray *transparentPaths; // 透明区数组

@end

@implementation SingleMaskView

- (instancetype)initWithFrame:(CGRect)frame {

self = [super initWithFrame: [UIScreen mainScreen].bounds];
if (self) {
[self setUp];
}

return self;
}

- (void)setUp {
self.backgroundColor = [UIColor clearColor];
self.maskColor = [UIColor colorWithWhite:0 alpha:0.5]; // default 50% transparent black

self.fillLayer.path = self.overlayPath.CGPath;
self.fillLayer.fillRule = kCAFillRuleEvenOdd;
self.fillLayer.fillColor = self.maskColor.CGColor;

// UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissMaskView)];
// [self addGestureRecognizer:tapGesture];
}

- (void)layoutSubviews {
[super layoutSubviews];

[self refreshMask];
}

- (void)refreshMask {

UIBezierPath *overlayPath = [self generateOverlayPath];

for (UIBezierPath *transparentPath in self.transparentPaths) {
[overlayPath appendPath:transparentPath];
}

self.overlayPath = overlayPath;

self.fillLayer.frame = self.bounds;
self.fillLayer.path = self.overlayPath.CGPath;
self.fillLayer.fillColor = self.maskColor.CGColor;
}

- (UIBezierPath *)generateOverlayPath {

UIBezierPath *overlayPath = [UIBezierPath bezierPathWithRect:self.bounds];
[overlayPath setUsesEvenOddFillRule:YES];

return overlayPath;
}

- (void)addTransparentPath:(UIBezierPath *)transparentPath {
[self.overlayPath appendPath:transparentPath];

[self.transparentPaths addObject:transparentPath];

self.fillLayer.path = self.overlayPath.CGPath;
}

- (void)addTransparentRect:(CGRect)rect withRadius:(CGFloat)radius{

UIBezierPath *transparentPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];

[self addTransparentPath:transparentPath];
}

- (void)addTransparentOvalRect:(CGRect)rect {
UIBezierPath *transparentPath = [UIBezierPath bezierPathWithOvalInRect:rect];

[self addTransparentPath:transparentPath];
}

- (void)addImage:(UIImage*)image withFrame:(CGRect)frame{

UIImageView * imageView = [[UIImageView alloc]initWithFrame:frame];
imageView.backgroundColor = [UIColor clearColor];
imageView.image = image;

[self addSubview:imageView];
}

- (void)showMaskViewInView:(UIView *)view{
self.alpha = 0;
[view addSubview:self];
[UIView animateWithDuration:0.3 animations:^{
self.alpha = 1;
}];
}

- (void)dismissMaskView{
__weak typeof(self)weakSelf = self;
[UIView animateWithDuration:0.3 animations:^{
weakSelf.alpha = 0;
} completion:^(BOOL finished) {
[weakSelf removeFromSuperview];
}];
}

#pragma mark - 懒加载Getter Methods

- (UIBezierPath *)overlayPath {
if (!_overlayPath) {
_overlayPath = [self generateOverlayPath];
}

return _overlayPath;
}

- (CAShapeLayer *)fillLayer {
if (!_fillLayer) {
CAShapeLayer *fillLayer = [CAShapeLayer layer];
fillLayer.frame = self.bounds;
[self.layer addSublayer:fillLayer];

_fillLayer = fillLayer;
}

return _fillLayer;
}

- (NSMutableArray *)transparentPaths {
if (!_transparentPaths) {
_transparentPaths = [NSMutableArray array];
}

return _transparentPaths;
}


- (void)setMaskColor:(UIColor *)maskColor {
_maskColor = maskColor;

[self refreshMask];
}
@end

MaskView.swift 继承SingleMaskView实现自定义(根据自己需要),如果项目使用的Swift开发,需要在桥接文件中#import “SingleMaskView.h” :

import Foundation

class MaskView: SingleMaskView
{
//新建“知道啦”点击按钮
override init(frame: CGRect) {
let button=UIButton(frame: CGRect(x: CGFloat((UIScreen.main.bounds.size.width-180) / 2), y: CGFloat(UIScreen.main.bounds.size.height - 200), width: CGFloat(UIScreen.main.bounds.size.width-150), height: CGFloat(60)))
button.setBackgroundImage(UIImage(named:"guide_next_setp.png"),for:.normal)
super.init(frame: frame)
button.addTarget(self, action: #selector(MaskView.clickFunc), for: UIControlEvents.touchDown)
self.addSubview(button)
}

convenience init() {
self.init(frame:CGRect.zero)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

//点击按钮消失
func clickFunc()
{
dismissMaskView()
}
}

调用方法:

//添加蒙版指引
let maskView = MaskView()
//添加图片
maskView.add(UIImage(named: "guide_job_detal_case.png"), withFrame: CGRect(x: CGFloat((UIScreen.main.bounds.size.width-350) / 2), y: CGFloat(UIScreen.main.bounds.size.height - 600), width: CGFloat(UIScreen.main.bounds.size.width-20), height: CGFloat(60)))
maskView.add(UIImage(named: "guide_job_detal_des.png"), withFrame: CGRect(x: CGFloat((UIScreen.main.bounds.size.width-350) / 2), y: CGFloat(UIScreen.main.bounds.size.height - 530), width: CGFloat(UIScreen.main.bounds.size.width-20), height: CGFloat(100)))
maskView.showMaskView(in: self.view)

实现效果:

Swift 蒙版操作指引_ide