Reputation: 3164
I am trying to achieve something like this:
Where the pink part is fixed and the grey area could possibly scroll. I have the following view structure:
I currently have this code:
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
}
}
The Mask View is set to have the grey background color.
The problem that I have is that the circular part is not transparent. Changing the color to UIColor.clear
will only make the circular part to disappear. Am I fundamentally doing the wrong approach for this? Any help would be appreciated, thanks.
Upvotes: 2
Views: 2073
Reputation: 33036
First of all, we need to create a subclass from UIView
(which you already did). But here is the code that I used:
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
}
}
Then you can add a MaskView
as a subView in the ViewController
. Make sure select the view assigned the class MaskView
in the storyboard:
Now we have a very simply view hierarchy:
Compiles the code and it's looking great:
If you want a scrollable subview that is masked, add it as a subview of the maskView. Here is how the view hierarchy looks after this:
And finally, this is how it looks running in the simulator:
Ref: https://github.com/yzhong52/Example-LayerMask
Upvotes: 2