В Swift не работает анимация рисования - PullRequest
0 голосов
/ 08 мая 2020

Снимок экрана

Я создал собственный класс UIButton, в котором я заполняю его внутреннюю часть цветом, но только частично.

Цель: цель состоит в том, чтобы заполните внутреннюю часть кнопки цветом фона, но только частично. Например, у вас длинная кнопка (высота: 50,0, ширина: 300,0). Я хочу заполнить его цветом фона по горизонтали, скажем, только на 50%. В этом случае только половина моей кнопки будет заполнена цветом, другая половина останется прозрачной или белой.

Весь класс выглядит так:

class CustomButton: UIButton {

    var color: UIColor = .clear
    var percentage: CGFloat = 0

    func fill(withPercentage percentage: CGFloat, isCorrect correct: Bool, onRect rect: CGRect) {
        self.color = correct ? .lightishGreen : .pastelRed
        self.percentage = percentage

        draw(rect)
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        let fillRect = CGRect(
            origin: CGPoint(x: rect.origin.x, y: rect.origin.y),
            size: CGSize(width: rect.size.width * percentage, height: rect.size.height)
        )
        color.set()

        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.fill(fillRect)
    }
}

и этот класс работает отлично . Однако я хочу оживить этот процесс рисования, поэтому кнопка заполняется цветом фона от 0,0 до 1,0, скажем.

Я пытался поместить context.fill(fillRect) внутри UIView.animate(){}, но это сработало не работает. Я подумал, а можно ли анимировать рисунок?

Я просто не хочу, чтобы цвет кнопки был прозрачным, а за ним помещал UIView и имитировал заливку. Хотел чистый путь. Так что буду рад, если кто-нибудь подскажет или покажет, как это сделать. Заранее спасибо!

1 Ответ

0 голосов
/ 09 мая 2020

Мне кажется, вам нужно настраиваемое свойство анимации. Назовем его percentage. Вот один из способов:

class MyView : UIView {
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.backgroundColor = .clear
    }
    override class var layerClass : AnyClass {
        return MyLayer.self
    }
    override func draw(_ rect: CGRect) {}
}
class MyLayer : CALayer {
    @NSManaged var percentage : CGFloat
    override class func needsDisplay(forKey key: String) -> Bool {
        if key == #keyPath(percentage) {
            return true
        }
        return super.needsDisplay(forKey:key)
    }
    override func action(forKey key: String) -> CAAction? {
        if key == #keyPath(percentage) {
            let ba = CABasicAnimation(keyPath: key)
            ba.fromValue = self.presentation()!.value(forKey:key)
            return ba
        }
        return super.action(forKey:key)
    }
    override func draw(in con: CGContext) {
        con.setFillColor(UIColor.green.cgColor)
        let rect = self.bounds.insetBy(dx: 2, dy: 2)
        let rounded = UIBezierPath.init(roundedRect: rect, cornerRadius: 20)
        con.addPath(rounded.cgPath)
        con.setStrokeColor(UIColor.lightGray.cgColor)
        con.strokePath()
        con.addPath(rounded.cgPath)
        con.clip(using: .evenOdd)
        let fillRect = CGRect(
            origin: CGPoint(x: rect.origin.x, y: rect.origin.y),
            size: CGSize(width: rect.size.width * percentage, height: rect.size.height)
        )
        con.fill(fillRect)
    }
}

В результате, когда вы устанавливаете percentage слоя этого представления, изменение анимируется:

enter image description here

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