@Rincewind, here's my summary of findings:
There seems to be an issue in iOS 10 that causes the UIView.mask property to not work when set on UIVisualEffectView when done so in viewWillLayoutSubviews(). When done in viewDidLoad(), works fine (But wont work if views are setup with Auto Layout). That same code works on UIView, with and without auto layout in iOS 10 in viewWillLayoutSubviews(). The same code also works in iOS 11 for both UIView and UIVisualEffectView in viewWillLayoutSubviews().
I'm not sure where to go from here to try to get top rounded corners for a UIVisualEffectView on iOS 10. Any help is much appreciated.
class PassthroughView: UIView {
override class var layerClass: AnyClass {
get {
return CAShapeLayer.self
}
}
private var corners = UIRectCorner.allCorners
private var radius: CGFloat = 10.0
required init(frame: CGRect, corners: UIRectCorner = .allCorners, radius: CGFloat = 10.0) {
super.init(frame: frame)
self.corners = corners
self.radius = radius
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
guard let layer = layer as? CAShapeLayer else {
return
}
layer.fillColor = UIColor.black.cgColor
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
layer.path = path.cgPath
}
}
class ViewController: UIViewController {
@IBOutlet weak var myView: UIView!
private let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(blurView)
blurView.frame = CGRect(x: 16, y: 328, width: 337, height: 218)
/ / This works for UIVisualEffectView in iOS 10, but fails if views are setup via Auto Layout
let passView = PassthroughView(frame: blurView.bounds, corners: [.topRight, .topLeft], radius: 10.0)
blurView.mask = passView
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
/ / This causes UIVisualEffectView to not be shown in iOS 10.
let passView = PassthroughView(frame: blurView.bounds, corners: [.topRight, .topLeft], radius: 10.0)
blurView.mask = passView
/ / This works
let passView2 = PassthroughView(frame: myView.bounds, corners: [.topRight, .topLeft], radius: 10.0)
myView.mask = passView2
}
}