更新时间:2023-11-04 09:39:58
我建议为你的面具画一条路径,例如在 Swift 3 中
I'd suggest drawing a path for your mask, e.g. in Swift 3
// BottomOverlayView.swift
import UIKit
@IBDesignable
class BottomOverlayView: UIView {
@IBInspectable
var radius: CGFloat = 100 { didSet { updateMask() } }
override func layoutSubviews() {
super.layoutSubviews()
updateMask()
}
private func updateMask() {
let path = UIBezierPath()
path.move(to: bounds.origin)
let center = CGPoint(x: bounds.midX, y: bounds.minY)
path.addArc(withCenter: center, radius: radius, startAngle: .pi, endAngle: 0, clockwise: false)
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
path.close()
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
注意,我对此进行了调整以在两个位置设置蒙版:
Note, I tweaked this to set the mask in two places:
来自 layoutSubviews
:这样,如果框架发生变化,例如由于自动布局(或通过手动更改 frame
或其他方式),它将相应更新;和
From layoutSubviews
: That way if the frame changes, for example as a result of auto layout (or by manually changing the frame
or whatever), it will update accordingly; and
如果您更新 radius
:这样,如果您在故事板中使用它或以编程方式更改半径,它将反映该更改.
If you update radius
: That way, if you're using this in a storyboard or if you change the radius programmatically, it will reflect that change.
因此,您可以在深蓝色 UIView
之上叠加半高的浅蓝色 BottomOverlayView
,如下所示:
So, you can overlay a half height, light blue BottomOverlayView
on top of a dark blue UIView
, like so:
结果:
如果您想使用重复答案中建议的切一个洞"技术,updateMask
方法将是:
If you wanted to use the "cut a hole" technique suggested in the duplicative answer, the updateMask
method would be:
private func updateMask() {
let center = CGPoint(x: bounds.midX, y: bounds.minY)
let path = UIBezierPath(rect: bounds)
path.addArc(withCenter: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true)
let mask = CAShapeLayer()
mask.fillRule = .evenOdd
mask.path = path.cgPath
layer.mask = mask
}
我个人认为在具有奇偶规则的路径中的路径有点违反直觉.在我可以的地方(例如这种情况),我更喜欢只绘制蒙版的路径.但是,如果您需要一个有切口的遮罩,这种奇偶填充规则方法会很有用.
I personally find the path within a path with even-odd rule to be a bit counter-intuitive. Where I can (such as this case), I just prefer to just draw the path of the mask. But if you need a mask that has a cut-out, this even-odd fill rule approach can be useful.