How to mask a View with many sub views in Swift?

Viewed 186

Masks in Swift have caused me to pull out all my hair, I'm now in the #baldclub.

I have a menu view that contains many sub views which also have many subviews. I need to mask the entire menu view so that the menu view can be animated to slide out under a button.

I have tried to simplify the problem with one container view and one subview and still have not been able to mask the views! Perhaps masks are afraid of auto-layout?

Here are the views:

let curtainMask: UIView = {
    let view = UIView()
    view.backgroundColor = .green
    view.isUserInteractionEnabled = false
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

let curtainContainer: UIView = {
    let view = UIView()
    view.backgroundColor = .clear
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

let locationImage: UIImageView = {
    let view = UIImageView()
    //view.layer.cornerRadius = 100
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .clear
    view.alpha = 1
    view.image = UIImage(systemName: "mappin")?.withRenderingMode(.alwaysOriginal)
    view.contentMode = .scaleAspectFit
    return view
}()

Here is the code being run on the main thread:

view.addSubview(curtainContainer)
curtainContainer.backgroundColor = .lightGray

curtainContainer.anchor(top: nil, left: nil, bottom: nil, right: nil, centerX: view.centerXAnchor, centerY: view.centerYAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 300, height: 200)


curtainContainer.addSubview(locationImage)
locationImage.anchor(top: curtainContainer.topAnchor, left: curtainContainer.leftAnchor, bottom: curtainContainer.bottomAnchor, right: curtainContainer.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)

view.addSubview(curtainMask)
curtainMask.backgroundColor = .green

curtainMask.anchor(top: nil, left: nil, bottom: nil, right: nil, centerX: view.centerXAnchor, centerY: view.centerYAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 200, height: 100)

view.layoutSubviews()
view.setNeedsLayout()

curtainContainer.mask = curtainMask

This code crates a large gray rectangle with an image as a subview. The mask is a smaller rectangle inside the large gray rectangle. I would expect the curtainContainer view to be masked along with the image subview but the result is that nothing is drawn. Any ideas?

0 Answers
Related