swift - 使用 mask 层使 UIView 的某些部分透明

标签 swift uibezierpath cashapelayer

我正在努力实现这样的目标:

enter image description here

粉色部分是固定的,灰色部分可以滚动。我有以下 View 结构:

enter image description here

我目前有这个代码:

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
    }

}

mask View 设置为灰色背景颜色。

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

最佳答案

首先,我们需要从 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 作为 subview 。确保在 Storyboard中选择分配了 MaskView 类的 View :

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

编译代码,看起来很棒:

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

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

引用号:https://github.com/yzhong52/Example-LayerMask

关于swift - 使用 mask 层使 UIView 的某些部分透明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43697972/

相关文章:

swift - 如何从我的 UIView 中删除 CAShapeLayer 和 CABasicAnimation?

objective-c - 使用 CABasicAnimation 为 CAShapeLayer 的 strokeColor 设置动画

ios - 检测 CAShapeLayer 中点击的位置

ios - 如何设置 UIBezierPath 边框以在 ios 中查看?

swift - UIBezierPath 的快速替代品

ios - Swift ios 在数组中存储数据和字符串

ios - 将 AVPlayerItem 保存到文档目录

objective-c - 在 Objective-C 中绘制具有开始和结束角度的椭圆

swift - 根据文本字段中的内容清除文本输入

swift - 使用协议(protocol)切换通用数值函数