使用drawrect自定义UIView动画
Posted
技术标签:
【中文标题】使用drawrect自定义UIView动画【英文标题】:Custom UIView animation using drawrect 【发布时间】:2015-03-12 19:43:46 【问题描述】:我在情节提要中创建了一个 UIView,并链接到一个名为“XXX”的自定义 UIView 类。在drawRect中我写了代码来填充XXX的颜色。从我的视图控制器我正在尝试为 UIView 设置动画。正在填充 XXX(UIView) 中的颜色,但没有动画。这是我的代码。
class XXX: UIView
override init(frame: CGRect)
super.init(frame: frame)
override func drawRect(rect: CGRect)
var context: CGContextRef = UIGraphicsGetCurrentContext()!
CGContextClearRect(context, rect)
let color = UIColor.greenColor().CGColor
CGContextSetFillColorWithColor(context, color)
CGContextAddRect(context, rect)
CGContextFillPath(context)
myviewcontroller.swift
@IBOutlet var xxxView: XXX!
override func viewDidLoad()
super.viewDidLoad()
XXX.animateWithDuration(1.0, delay: 0, options:
UIViewAnimationOptions.Repeat, animations: () -> Void in
XXX.setAnimationDuration(1.0)
self.xxxView = XXX (frame: CGRectMake(0, 0, 100, 100))
,completion: nil);
我在视图控制器动画中犯了一些错误。想不通。那么,如何为自定义 UIView 设置动画?或者如何对drawrect的内容进行动画处理?
注意:drawRect 被调用并且 rect 被颜色填充但没有动画。 我之前的方法只是在控制器中创建一个 UIView 并通过动画增加宽度。但是,它没有被团队接受。像下面这样的东西,工作正常。
var xxxView = UIView()
xxxView.frame = CGRectMake(0, 10, startingPoint, 20)
xxxView.backgroundColor = UIColor.greenColor()
UIView.animateWithDuration(1.0, delay: 0, options:
UIViewAnimationOptions.Repeat, animations: () -> Void in
UIView.setAnimationDuration(3.0)
let totalWidth: CGFloat = 50
let animationWidth: CGFloat = totalWidth - startingPoint
var frame : CGRect = xxxView.frame;
frame.size.width = (startingPoint + animationWidth)
xxxView.frame = frame;
,completion: nil);
谢谢!
【问题讨论】:
【参考方案1】:更新 我明白你现在在问什么,我一开始误解了。您希望在不实际为视图设置动画的情况下对 UIView 的填充进行动画处理(不知道为什么)。
在您的 drawRect 内部而不是使用提供的 rect 变量,使用值为 0 的自定义“currentHeight”变量创建您自己的变量,然后使用动画块或计时器增加您的“currentHeight”变量直到它已满.
您可以使用 CADisplayLink 调用函数来调用“setNeedsDisplay”以触发重绘,因为为自定义变量设置动画不会触发对绘图的更新(尽管也许您可以为另一个变量设置动画来触发它,但这是草率的但可能有效)。
抱歉,我无法提供更好的解释或示例,但我现在不在笔记本电脑旁。
问题是您在动画块内创建了一个全新的 xxxView 实例,而不是为现有实例设置动画。
如果你想让你的视图动画,你需要在你的动画块之外(使用故事板或代码)初始化你现有的 self.xxxView 到你的起点,在你的动画块内部调整你想要动画的值。例如:
override func viewDidLoad()
super.viewDidLoad()
self.xxxView = XXX(frame:CGRectMake(0,0,100,100) //set starting point here or set it in storyboard
XXX.animateWithDuration(1.0, delay: 0, options:
UIViewAnimationOptions.Repeat, animations: () -> Void in
XXX.setAnimationDuration(1.0)
self.xxxView.alpha = 1
,completion: nil);
此代码将初始化一个 alpha 为 0 的视图,然后将其设置为 alpha 为 1 的动画,持续时间为 1 秒。
如果你想让它看起来好像被颜色填充了,你可以使用调整视图大小的技巧。这与在动画块中操作现有视图的属性的概念相同。
例子:
override func viewDidLoad()
super.viewDidLoad()
self.xxxView = XXX(frame:CGRectMake(0,0,0,0) //set starting point here or set it in storyboard
self.xxxView.alpha = 0
XXX.animateWithDuration(1.0, delay: 0, options:
UIViewAnimationOptions.Repeat, animations: () -> Void in
XXX.setAnimationDuration(1.0)
self.xxxView.frame = CGRectMake(0,0,100,100)
,completion: nil);
【讨论】:
在我的 drawRect 中,我正在为 uiview 填充颜色。这个填充操作应该是动画的。 我已经用另一个例子更新了答案,你可以操纵大小和位置来获得你想要的效果。我不在电脑前测试,但它应该可以工作,原理就在那里。 如果我按照你的建议去做,那么这就像我之前提到的作为我问题的一部分的方法。 啊,我明白了,对不起,我没有意识到这一点。我已经用一个建议更新了我的答案。 这种思维方式对不对? “在没有实际动画视图的情况下对 UIView 进行动画填充(不知道为什么)”.. 现在我认为这不是正确的方法。因此,在 drawrect 中绘制任何东西并在动画块中为某些东西设置动画。【参考方案2】:我认为你的问题是当视图加载时,它已经加载了动画。当视图出现时,您希望它具有动画效果。试着把它放在 override func viewDidAppear() 中。
【讨论】:
如果我移动到 viewDidAppear()。 drawRect 已经在 UIView 中填充了颜色,然后尝试制作动画。因为,UIView 存在于故事板中,从那里链接到自定义视图(XXX)。【参考方案3】:如果您只需要通过动画更改 UIView 的颜色,那么最简单的方法是使用 backgroundColor
属性并在动画块中进行更改,如下所示:
UIView.animateWithDuration(duration:1.0, animations: () -> Void in
myView.backgroundColor = UIColor.greenColor();
)
请记住,animateWithDuration
func 是一个类 func,因此您不会在 UIView
的实例上调用它,而是在类本身上调用它。
在动画drawRect:
方法方面,这更复杂,我无法给你一个明确的答案。一种选择是使用CAAnimation
对象并将其添加到视图的layer
中,用于属性backgroundColor
,如下所示:
var animation : CABasicAnimation = CABasicAnimation(keyPath:"backgroundColor")
animation.fromValue = myView.backgroundColor
animation.toValue = UIColor.greenColor
animation.duration = 1.0
myView.layer.backgroundColor = UIColor.greenColor.CGColor
myView.layer.addAnimation(animation, forKey:"backgroundColor")
注意:以上代码未经测试,旨在给出一个不确定的想法。这也假设您想要从一种颜色到另一种颜色的漂亮淡入淡出动画。对于自定义动画,例如从上到下填充,您需要执行其他操作,例如添加子图层并为其大小变化设置动画。
【讨论】:
以上是关于使用drawrect自定义UIView动画的主要内容,如果未能解决你的问题,请参考以下文章
在自定义 UIView 中动画 UIBezierPath 不起作用
我真的需要在自定义 UIView 中使用 drawRect() 吗?
使用 CGAffineTransformScale 自定义 UIView 缩放
即使使用 UIViewContentModeScaleAspectFill 也会调用自定义 UIView drawRect