Swift - Как использовать режим наложения UIGraphics? - PullRequest
2 голосов
/ 25 января 2020

Я бы хотел разработать анимацию индикатора выполнения для AppleWatch. Я решил сделать все это с помощью UIGraphicContext .

Так как я начинающий, я не совсем понимаю, как я могу применить своего рода « globalCompositeOperation » к своему контексту.

Чтобы лучше проиллюстрировать мою идею вот несколько картинок:

Image #1

Image #2

Image #3


Это мой исходный код до сих пор:

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()

Я полагаю, что это неправильный подход, потому что результат выглядит примерно так:

Image #4

Любая помощь будет принята с благодарностью. Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 26 января 2020

На основании ответа @ matt, используя .sourceAtop Я нашел рабочее решение для 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()
1 голос
/ 25 января 2020

Вы хотите .sourceAtop. Вот демонстрация:

    let green = UIImage(named:"green.png")! // your original 5 green rects
    let sz = green.size
    let red = UIGraphicsImageRenderer(size:sz).image {
        ctx in
        UIColor.red.setFill()
        // width value determines how much we will fill
        ctx.fill(CGRect(x: 0, y: 0, width: sz.width/2, height: sz.height))
    }
    let result = UIGraphicsImageRenderer(size:sz).image {
        ctx in
        green.draw(at: .zero)
        red.draw(at: .zero, blendMode: .sourceAtop, alpha: 1)
    }

enter image description here

Просто измените значение на width: sz.width/2 для разных величин "термометра".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...