今天想做一个根据进度变化的动画,因此写了一个循环做实验。大致的结构就是在一个循环内不断更新一个变量并且更新动画。
但是发现每次都是循环结束的时候动画才执行,即只执行了最后一次。
然后去google,发现了这样一段话。
When a content of the view is changed and needs to be redrawn you can invalidate the view by calling setNeedsDisplay: or setNeedsDisplayInRect: methods. When
one of these method is called, it says the system to redraw the view. Before drawing the requested view the system will wait for the current
run loop to finish. This delay help us to do further changes to the view's properties or you can even add or remove views from the hierarchy
and finally all the changes will get effect at the end of the current run loop.
上面标红的地方是重点,就是只有当前runloop结束的时候才会重新绘制动画。而且drawRect方法不能直接调用。
每一个线程都有一个runloop,只要让程序在一个runloop中循环,在另一个runloop中重绘就好了。
所以方法如下:
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
float progress = 0.0f;
while (progress < 1.0f) {
//更新变量
dispatch_async(dispatch_get_main_queue(), ^{
//更新动画
});
<span style="white-space:pre"> </span>//这里可以等待一下,防止太快
}
});