How to get multiply blend mode on a plain UIView (not UIImage) How to get multiply blend mode on a plain UIView (not UIImage) ios ios

How to get multiply blend mode on a plain UIView (not UIImage)


Take a look at the docs for CALayer's compositingFilter: https://developer.apple.com/documentation/quartzcore/calayer/1410748-compositingfilter

On your color overlay view you can set view.layer.compositingFilter to a CICategoryCompositeOperation to achieve blending with the content behind it. Here is some sample playground code with a multiply blend mode applied to test it out (replace the UIImage(named: "") with your own image for testing)

import UIKitimport PlaygroundSupportclass MyViewController : UIViewController {    override func loadView() {        let mainView = UIView()        self.view = mainView        let image = UIImageView()        image.translatesAutoresizingMaskIntoConstraints = false;        image.image = UIImage(named: "maxresdefault.jpg")        mainView.addSubview(image)        let overlay = UIView()        overlay.translatesAutoresizingMaskIntoConstraints = false;        overlay.backgroundColor = .red        overlay.layer.compositingFilter = "multiplyBlendMode"        mainView.addSubview(overlay)        mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": view]))        mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": view]))        mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": overlay]))        mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": overlay]))    }}PlaygroundPage.current.liveView = MyViewController()


iOS 13, Swift 5

The key is setting the compositingFilter property on the appropriate CALayer (the one on top - it blends with whatever is behind it). Color blending works between UIViews or CALayers. You can find blending modes here CICategoryCompositeOperation. To use a filter, just drop the CI & lowercase the first letter of the name (e.g. CIDivideBlendMode becomes divideBlendMode). Here is some playground code to illustrate:

import UIKitimport PlaygroundSupportlet view = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 900))PlaygroundPage.current.liveView = viewlet heightIncrement = view.frame.height / 13let widthIncrement = view.frame.width / 7// TOP EXAMPLE (UIViews)let backgroundView = UIView(frame: CGRect(x: widthIncrement * 2,                                          y: heightIncrement,                                          width: widthIncrement * 3,                                          height: heightIncrement * 5))backgroundView.backgroundColor = .blackview.addSubview(backgroundView)let overlayView1 = UIView(frame: CGRect(x: widthIncrement,                                        y: heightIncrement * 2,                                        width: widthIncrement * 5,                                        height: heightIncrement))overlayView1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)overlayView1.layer.compositingFilter = "darkenBlendMode"view.addSubview(overlayView1)let overlayView2 = UIView(frame: CGRect(x: widthIncrement,                                        y: heightIncrement * 4,                                        width: widthIncrement * 5,                                        height: heightIncrement))overlayView2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)overlayView2.layer.compositingFilter = "divideBlendMode"view.addSubview(overlayView2)// BOTTOM EXAMPLE (CALayers)let backgroundLayer = CALayer()backgroundLayer.frame = CGRect(x: widthIncrement * 2,                               y: heightIncrement * 7,                               width: widthIncrement * 3,                               height: heightIncrement * 5)backgroundLayer.backgroundColor = UIColor.black.cgColorview.layer.addSublayer(backgroundLayer)let overlayLayer1 = CALayer()overlayLayer1.frame = CGRect(x: widthIncrement,                             y: heightIncrement * 8,                             width: widthIncrement * 5,                             height: heightIncrement)overlayLayer1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColoroverlayLayer1.compositingFilter = "darkenBlendMode"view.layer.addSublayer(overlayLayer1)let overlayLayer2 = CALayer()overlayLayer2.frame = CGRect(x: widthIncrement,                             y: heightIncrement * 10,                             width: widthIncrement * 5,                             height: heightIncrement)overlayLayer2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColoroverlayLayer2.compositingFilter = "divideBlendMode"view.layer.addSublayer(overlayLayer2)

The result looks like this:

description

I confirmed that the same code works in iOS. Here's the view controller code:

import UIKitclass ViewController: UIViewController {    override func viewDidLoad() {        super.viewDidLoad()    }    override func viewDidAppear(_ animated: Bool) {        super.viewDidAppear(animated)        let heightIncrement = view.frame.height / 13        let widthIncrement = view.frame.width / 7        // TOP EXAMPLE (UIViews)        let backgroundView = UIView(frame: CGRect(x: widthIncrement * 2,                                                  y: heightIncrement,                                                  width: widthIncrement * 3,                                                  height: heightIncrement * 5))        backgroundView.backgroundColor = .black        view.addSubview(backgroundView)        let overlayView1 = UIView(frame: CGRect(x: widthIncrement,                                                y: heightIncrement * 2,                                                width: widthIncrement * 5,                                                height: heightIncrement))        overlayView1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)        overlayView1.layer.compositingFilter = "darkenBlendMode"        view.addSubview(overlayView1)        let overlayView2 = UIView(frame: CGRect(x: widthIncrement,                                                y: heightIncrement * 4,                                                width: widthIncrement * 5,                                                height: heightIncrement))        overlayView2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)        overlayView2.layer.compositingFilter = "divideBlendMode"        view.addSubview(overlayView2)        // BOTTOM EXAMPLE (CALayers)        let backgroundLayer = CALayer()        backgroundLayer.frame = CGRect(x: widthIncrement * 2,                                       y: heightIncrement * 7,                                       width: widthIncrement * 3,                                       height: heightIncrement * 5)        backgroundLayer.backgroundColor = UIColor.black.cgColor        view.layer.addSublayer(backgroundLayer)        let overlayLayer1 = CALayer()        overlayLayer1.frame = CGRect(x: widthIncrement,                                     y: heightIncrement * 8,                                     width: widthIncrement * 5,                                     height: heightIncrement)        overlayLayer1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor        overlayLayer1.compositingFilter = "darkenBlendMode"        view.layer.addSublayer(overlayLayer1)        let overlayLayer2 = CALayer()        overlayLayer2.frame = CGRect(x: widthIncrement,                                     y: heightIncrement * 10,                                     width: widthIncrement * 5,                                     height: heightIncrement)        overlayLayer2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor        overlayLayer2.compositingFilter = "divideBlendMode"        view.layer.addSublayer(overlayLayer2)    }}

And here's the result in the simulator:

description