我想知道如何简单地掩盖任何类型的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;
答案 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;
}
}
<强>输出强>
答案 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
是正确的方法。