【问题标题】:Make parts of UIView transparent by using a masking layer使用遮罩层使部分 UIView 透明
【发布时间】:2017-04-29 16:27:48
【问题描述】:

我正在尝试实现这样的目标:

粉色部分是固定的,灰色区域可能会滚动。我有以下视图结构:

我目前有这个代码:

extension FloatingPoint {

    var degreesToRadians: Self { return self * .pi / 180 }
    var radiansToDegrees: Self { return self * 180 / .pi }

} 

@IBDesignable
class MaskView: UIView {

    let startAngle: CGFloat = 180
    let endAngle: CGFloat = 0

    override func layoutSubviews() {
        super.layoutSubviews()

        let multiplier: CGFloat = (frame.size.height * 3)
        let maskLayer = CAShapeLayer()
        maskLayer.path = UIBezierPath(arcCenter: CGPoint(x: frame.size.width/2, y: frame.size.height * multiplier),
                                  radius: frame.size.height * multiplier,
                                  startAngle: startAngle.degreesToRadians,
                                  endAngle: endAngle.degreesToRadians,
                                  clockwise: true).cgPath

        layer.mask = maskLayer
    }

}

蒙版视图设置为具有灰色背景色。

我遇到的问题是圆形部分不透明。将颜色更改为UIColor.clear 只会使圆形部分消失。我是否从根本上为此采取了错误的方法?任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 请问您如何更改“要清除的颜色”?你能告诉我们你的代码吗?
  • 我在情节提要中这样做了,但在代码中它将是 backgroundColor = UIColor.clear
  • 乘数应该是 3 而不是 frame.size.height * 3 let multiplier: CGFloat = 3
  • 神秘的乘数只是我试图弄清楚如何绘制所有屏幕宽度相等的圆,但这是另一回事..

标签: swift uibezierpath cashapelayer


【解决方案1】:

首先,我们需要从UIView 创建一个子类(您已经这样做了)。但这是我使用的代码:

private extension FloatingPoint {
    var degreesToRadians: Self { return self * .pi / 180 }
    var radiansToDegrees: Self { return self * 180 / .pi }
}

@IBDesignable class MaskView: UIView {
    let startAngle: CGFloat = 180
    let endAngle: CGFloat = 0

    override func layoutSubviews() {
        super.layoutSubviews()

        // The multiplier determine how big the circle is
        let multiplier: CGFloat = 3.0
        let radius: CGFloat = frame.size.width * multipler
        let maskLayer = CAShapeLayer()
        let arcCenter = CGPoint(x: frame.size.width / 2, y: radius)
        maskLayer.path = UIBezierPath(arcCenter: arcCenter,
                                      radius: radius,
                                      startAngle: startAngle.degreesToRadians,
                                      endAngle: endAngle.degreesToRadians,
                                      clockwise: true).cgPath
        layer.mask = maskLayer
    }
}

然后您可以在ViewController 中添加MaskView 作为子视图。确保在情节提要中选择分配给 MaskView 类的视图:

现在我们有了一个非常简单的视图层次结构:

编译代码,它看起来很棒:

如果您想要一个被屏蔽的可滚动子视图,请将其添加为 maskView 的子视图。以下是视图层次结构在此之后的样子:

最后,这是它在模拟器中运行的样子:

参考:https://github.com/yzhong52/Example-LayerMask

【讨论】:

  • 嗨雨辰,谢谢。我尝试了您的示例,但得到了以下结果:i.stack.imgur.com/vDGfz.png 具有与您相同的视图层次结构,并且 MaskView 的高度为 150,固定在前导、尾随和顶部。
  • @José,很难说你做了什么不同的事情。我在这里推送了我的代码:github.com/yzhong52/Example-LayerMask。希望对您有所帮助。
  • 视图层次结构略有不同。好东西,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 2020-04-27
相关资源
最近更新 更多