使用swift和UIViewAnimation逐渐填充形状?

时间:2017-06-26 18:39:35

标签: ios swift uiview uianimation

我有一个iOS 10应用程序,其中包含一个按钮(“按我!”)和一个包含蓝色轮廓矩形的UIView,没有填充。我想用红色逐渐(用5秒钟)填充矩形,使用任何可能的方法(我尝试使用UIView.animation(withDuration:, animations:))。我将包括以下代码:

这是viewController:

class ViewController: UIViewController {

@IBOutlet weak var tronkyy: tronc!

override func viewDidLoad() {
    super.viewDidLoad()

}

@IBAction func didPress(_ sender: UIButton) {
    tronkyy.full = true
    tronkyy.setNeedsDisplay()
} }

观点:

@IBDesignable class tronc: UIView {

//var value = 0.0
var full = false

override func draw(_ rect: CGRect) {
    UIColor.blue.setStroke()
    boxPath().stroke()
    drawDynamic()
}

private func boxPath() -> UIBezierPath {
    let path = UIBezierPath(rect: CGRect(x: 0.1 * frame.width, y: 0.1 * frame.height, width: 0.8 * frame.width, height: 0.8 * frame.height))
    UIColor.blue.setStroke()
    return path
}

func drawDynamic() {
    if full {
        UIView.animate(withDuration: 10) { _ in
            //while self.value < 1 {
                let path = UIBezierPath(rect: CGRect(x: 0.1 * self.frame.width, y: 0.1 * self.frame.height, width: (0.8 * self.frame.width), height: 0.8 * self.frame.height)) //* CGFloat(value)))
                UIColor.red.setFill()
                path.fill()

                //self.value += 0.1
            //}
        }
        full = false
    }
} }

啊,是的,请忽略红色视图覆盖矩形。 问题是没有逐渐填充。它只是一劳永逸地填充它。

编辑:我注释掉了“value”属性和while循环,如答案所示,但它仍然不起作用。

2 个答案:

答案 0 :(得分:1)

这是一种使用具有子视图的视图的方法。对于比矩形更复杂的形状,可以使用蒙版来完成。

您可以直接在Playground页面中运行它:

import UIKit
import PlaygroundSupport

class TestViewController : UIViewController {

    let btn: UIButton = {
        let b = UIButton()
        b.setTitle("Tap Me", for: .normal)
        b.backgroundColor = .blue
        b.frame = CGRect(x: 20, y: 20, width: 200, height: 30)
        return b
    }()

    let blueRect: UIView = {
        let v = UIView()
        v.layer.borderColor = UIColor.blue.cgColor
        v.layer.borderWidth = 2.0
        v.backgroundColor = .clear
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    let redRect: UIView = {
        let v = UIView()
        v.backgroundColor = .red
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    var redRectHeightConstraint: NSLayoutConstraint?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.addSubview(btn)

        btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)


        blueRect.addSubview(redRect)
        self.view.addSubview(blueRect)

        redRect.leftAnchor.constraint(equalTo: blueRect.leftAnchor, constant: 0.0).isActive = true
        redRect.rightAnchor.constraint(equalTo: blueRect.rightAnchor, constant: 0.0).isActive = true
        redRect.bottomAnchor.constraint(equalTo: blueRect.bottomAnchor, constant: 0.0).isActive = true

        redRectHeightConstraint = NSLayoutConstraint(item: redRect,
                                                     attribute: .height,
                                                     relatedBy: .equal,
                                                     toItem: nil,
                                                     attribute: .notAnAttribute,
                                                     multiplier: 1.0,
                                                     constant: 0.0)

        redRect.addConstraint(redRectHeightConstraint!)

        blueRect.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.5).isActive = true
        blueRect.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5).isActive = true
        blueRect.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        blueRect.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true

    }

    func didTap(_ sender: Any?) -> Void {
        UIView.animate(withDuration: 5.0, animations: {
            _ in
            self.redRectHeightConstraint!.constant = self.blueRect.frame.size.height
            self.view.setNeedsLayout()
        }, completion: {
            finished in
        })

    }

}


let vc = TestViewController()
vc.view.backgroundColor = .yellow
vc.view.frame = CGRect(x: 0, y: 0, width: 600, height: 600)

PlaygroundPage.current.liveView = vc

注意:这只是示例,演示代码......并不是复制/粘贴解决方案。

答案 1 :(得分:0)

您不应在动画功能中使用while循环。试试这个版本

UIView.animate(withDuration: 10) { _ in
    let path = UIBezierPath(rect: CGRect(x: 0.1 * self.frame.width, y: 0.1 * self.frame.height, width: (0.8 * self.frame.width), height: 0.8 * self.frame.height))
    UIColor.red.setFill()
    path.fill()
}