Swift 蒙版操作指引

本文使用了蒙版工具类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)

实现效果:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值