如何绘制内层的面具?

时间:2017-11-10 14:51:41

标签: ios core-graphics

enter image description here

我正在使用以下代码来生成它(在drawRect内部):

let path = CGMutablePath()
path.addArc(center: self.circleCenter, radius: radius, startAngle: 0.0, endAngle: 2 * 3.14, clockwise: false)

let whitePath = UIBezierPath(cgPath: path)
UIColor.white.setStroke()
whitePath.lineWidth = 3
whitePath.stroke()


path.addRect(CGRect(x: 0, y: 0, width: frame.width, height: frame.height))

let maskLayer = CAShapeLayer()
maskLayer.backgroundColor = UIColor.black.cgColor
maskLayer.path = path
maskLayer.fillRule = kCAFillRuleEvenOdd

layer.mask = maskLayer

但是,我想将圆圈的顶部变白,以便整个圆圈内部是白色的,但我不确定如何做到这一点,因为我已经将layer.mask设置为是CAShape图层,所以我在这个圆圈内所做的任何绘图都不会显示出来。

掩码需要是一个圆圈,因为实际上对于我的大多数用例,对于这个自定义UIView,它不会剪切另一个视图的顶部,因此使用圆圈效果很好。如何画出圆圈的顶部区域?

编辑:我希望这部分(我用红色圈出的地方)填充白色:

enter image description here

所以我希望最终的图片看起来像(对不起质量不好,手动将它画在我的iPad上):

enter image description here

2 个答案:

答案 0 :(得分:2)

你说:

  

...“消息”来自下方的视图。暗影视图在顶部是UIView,我在暗影视图中有一个遮罩,所以我可以看到它下面。

以下是两种方法:

  1. 如果你真的想使用蒙版,你需要一个复杂的视图层次结构,它有四个主要视图:根视图(白色),铬视图(包含所有铬的视图,当你添加时将被屏蔽)您的圆形遮罩;例如,您需要遮盖的圆形顶部),将面具添加到镶边和调光视图时不会遮盖的UI元素视图,以及调光视图(也会被掩盖)。后三者需要是主视图的子视图(不要将消息按钮放在chrome视图上,而是将其设置为自己的视图,因此当您屏蔽掉chrome时,这些UI元素将不会被屏蔽掉)。

    你最终得到如下内容(这是在添加了面具后显示的):

    enter image description here

    然后,您可以使调光视图可见并屏蔽它和背景视图:

    @IBAction func didTapButton(_ sender: Any) {
        dimmingView.alpha = 0.5
        let center = messagingView.center
        let radius = messagingView.frame.width * 0.7
    
        mask(center: center, radius: radius, in: messagingView.superview!, on: dimmingView)
        mask(center: center, radius: radius, in: messagingView.superview!, on: backgroundView)
    }
    
    private func mask(center: CGPoint, radius: CGFloat, in view: UIView, on viewToMask: UIView) {
        let point = view.convert(center, to: viewToMask)
        let path = UIBezierPath(rect: viewToMask.bounds)
        path.addArc(withCenter: point, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true)
        let mask = CAShapeLayer()
        mask.fillColor = UIColor.white.cgColor
        mask.path = path.cgPath
        mask.fillRule = kCAFillRuleEvenOdd
        viewToMask.layer.mask = mask
    }
    

    因此,在调光视图不可见且没有遮罩的情况下,您可以使用前视图:

    enter image description here

    然后在调暗视图可见后,它和“chrome”视图都被屏蔽:

    enter image description here

  2. 更容易,恕我直言,将:

    • 拍摄消息快照视图;
    • 添加调光视图(隐藏消息视图);
    • 在调光视图的顶部添加圆形视图(不透明和白色);和
    • 在圈子顶部添加消息视图的快照(或其他再现)。

    这会产生一种感觉,就像你“揭示”消息按钮,但你真正在做的是添加你的调光视图,一个圆圈,以及另一个消息按钮的再现。这避免了为各种视图添加掩码的所有笨拙。

答案 1 :(得分:1)

面具不画,它掩盖。如果要将部分圆圈强制为白色,则需要绘制白色。如果您要覆盖drawRect,请在绘制图像后绘制想要为白色的区域。

如果你想创建一个你想要的视图,而不是覆盖drawRect,这通常是一个更好的方法,你可以在视图的图层上设置一个遮罩层,另外在你的上面添加另一个形状图层包含白色形状的图像视图。

相关问题