只需用矩形掩盖UIView即可

时间:2012-07-09 07:58:08

标签: ios uiview mask

我想知道如何简单地掩盖任何类型的UIView的可见区域。到目前为止,我所阅读的所有答案/教程都描述了使用图像,渐变或创建圆角进行遮罩,这种方法比我之后更加先进。

示例:我有一个带有边界(0,0,100,100)的UIView,我想用掩码切掉视图的右半部分。因此我的面具框架将是(0,0,50,100)。

知道如何做到这一点吗?我不想覆盖drawrect方法,因为这应该适用于任何UIView。

我已经尝试过了,但它只是让整个视图看不见。

CGRect mask = CGRectMake(0, 0, 50, 100);
UIView *maskView = [[UIView alloc] initWithFrame:mask];
viewToMask.layer.mask = maskView.layer;

7 个答案:

答案 0 :(得分:124)

感谢MSK提供的链接,这就是我使用的方式:

// Create a mask layer and the frame to determine what will be visible in the view.
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
CGRect maskRect = CGRectMake(0, 0, 50, 100);

// Create a path with the rectangle in it.
CGPathRef path = CGPathCreateWithRect(maskRect, NULL);

// Set the path to the mask layer.
maskLayer.path = path;

// Release the path since it's not covered by ARC.
CGPathRelease(path);

// Set the mask of the view.
viewToMask.layer.mask = maskLayer;

答案 1 :(得分:20)

根本不需要任何面具。 只需将其放入包装视图并使用较小的框架,然后设置clipsToBounds

wrapper.clipsToBounds = YES;

答案 2 :(得分:18)

谢谢你的回答。

如果有人在几个小时内无法在SO上找到合适的答案,就像我刚才那样,我已经在Swift 2.2中为masking / {{1}汇总了一个工作要点} clipping UIView / CGRect

https://gist.github.com/Flar49/7e977e81f1d2827f5fcd5c6c6a3c3d94

UIBezierPath

用法:

extension UIView {

    func mask(withRect rect: CGRect, inverse: Bool = false) {
        let path = UIBezierPath(rect: rect)
        let maskLayer = CAShapeLayer()

        if inverse {
            path.append(UIBezierPath(rect: self.bounds))
            maskLayer.fillRule = kCAFillRuleEvenOdd
        }

        maskLayer.path = path.cgPath

        self.layer.mask = maskLayer
    }

    func mask(withPath path: UIBezierPath, inverse: Bool = false) {
        let path = path
        let maskLayer = CAShapeLayer()

        if inverse {
            path.append(UIBezierPath(rect: self.bounds))
            maskLayer.fillRule = kCAFillRuleEvenOdd
        }

        maskLayer.path = path.cgPath

        self.layer.mask = maskLayer
    }
}

希望将来能节省一些时间:)

答案 3 :(得分:2)

Swift ViewController中非常简单的示例,基于接受的答案:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let redView = UIView(frame: view.bounds)
        view.addSubview(redView)

        view.backgroundColor = UIColor.greenColor()
        redView.backgroundColor = UIColor.redColor()

        mask(redView, maskRect: CGRect(x: 50, y: 50, width: 50, height: 50))
    }

    func mask(viewToMask: UIView, maskRect: CGRect) {
        let maskLayer = CAShapeLayer()
        let path = CGPathCreateWithRect(maskRect, nil)
        maskLayer.path = path

        // Set the mask of the view.
        viewToMask.layer.mask = maskLayer;
    }
}

<强>输出

enter image description here

答案 4 :(得分:1)

  

一个可选图层,其 alpha通道用作要选择的遮罩   在图层的背景和合成的结果之间   图层内容及其过滤后的背景。

     

@property(保留)CALayer * mask

执行所需操作的正确方法是创建与maskView要隐藏的图层相同的框架(0,0,100,100)的viewToMask。然后你需要为你想要隐藏的路径设置clearColor(这将阻止路径上的视图交互,所以要小心视图层次结构)。

答案 5 :(得分:0)

迅速5 ,谢谢@Dan Rosenstark

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let red = UIView(frame: view.bounds)
        view.addSubview(red)
        view.backgroundColor = UIColor.cyan
        red.backgroundColor = UIColor.red
        red.mask(CGRect(x: 50, y: 50, width: 50, height: 50))
    }
}

extension UIView{
    func mask(_ rect: CGRect){
        let mask = CAShapeLayer()
        let path = CGPath(rect: rect, transform: nil)
        mask.path = path
        // Set the mask of the view.
        layer.mask = mask
    }
}

答案 6 :(得分:-1)

设置MaskToBounds是不够的,例如,在UIImageView位于RelativeLayout内的情况下。如果您将UIImageView置于布局的上边缘附近然后旋转UIImageView,它将覆盖布局并且不会被裁剪。如果您将该标志设置为true,它将被裁剪为是,但如果UIImageView位于布局中心,它也将被裁剪,这不是您想要的。

因此,确定maskRect是正确的方法。