本文使用了蒙版工具类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)
实现效果: