Search code examples
iosswiftwatchkituigraphicscontext

Swift - How to use UIGraphics blend mode?


I would like to develop a kind of progress bar animation for AppleWatch. I decided to do it all with the UIGraphicContext.

Since I'm a complete beginner I don't really understand how I can apply some kind of "globalCompositeOperation" to my context.

To illustrate my idea better here are some pictures:

Image #1

Image #2

Image #3


This is my source code so far:

let size = CGSize(width: 300, height: 100)
UIGraphicsBeginImageContext(size)

let context = UIGraphicsGetCurrentContext()!

context.setFillColor(UIColor.red.cgColor)
context.fill(CGRect(x: 0.0, y: 0.0, width: size.width * 0.5, height: size.height))
context.setBlendMode(CGBlendMode.destinationOver)

let count = 5;
let padding = (size.width / CGFloat(count)) * 0.5
for i in 0...count {
    let offsetX = size.width * (CGFloat(i) / CGFloat(count))
    let rect = CGRect(x: offsetX + padding/2, y: 0, width: padding, height: size.height)
    context.setFillColor(UIColor.green.cgColor)
    context.fill(rect)
}
UIGraphicsEndImageContext()

I guess this is kind of the wrong approach because the result is more like this:

Image #4

Any help would be really appreciated. Thanks in advance.


Solution

  • Based on @matt's answer using .sourceAtop I found a working solution for WatchKit:

    let size = CGSize(width: 300, height: 100)
    UIGraphicsBeginImageContext(size)
    
    let context = UIGraphicsGetCurrentContext()!
    let count = 5;
    let padding = (size.width / CGFloat(count)) * 0.5
    for i in 0...count {
        let offsetX = size.width * (CGFloat(i) / CGFloat(count))
        let rect = CGRect(x: offsetX + padding/2, y: 0, width: padding, height: size.height)
        context.setFillColor(UIColor.green.cgColor)
        context.fill(rect)
    }
    
    context.setFillColor(UIColor.red.cgColor)
    context.setBlendMode(CGBlendMode.sourceAtop)
    context.fill(CGRect(x: 0.0, y: 0.0, width: size.width * 0.5, height: size.height))
    
    UIGraphicsEndImageContext()