一般情况下,不管目标是什么ios设备,你都应该避免频繁的调用-drawRect:。为了改善你的应用在iphone4上的性能这是特别关键的,因为相对于其他iphone你有4倍的像素量需要填充。
如果你偶然遇上了图片绘制性能的问题,那么可能你在你的视图的-drawRect:方法中使用CGContextDrawImage或 UIImage/-drawInRect:方法绘制图像,无效或快速重绘这个视图...
注意,因为 iPhone/iPod touch/iPad更新屏幕,如果你调用setNeedsDisplayInRect: 或 -setNeedsDisplay:,整个视图都会被重绘。
重要:每个UIView都是作为一个单个的元素。当你setNeedsDisplayInRect: or -setNeedsDisplay:请求部分或者全部重绘,整个的视图将被标记为更新。
每个UIView都支持CALayer和images作为layer的内容保存在内存中,只有CALayer还在视图层级中。意思是你在应用程序中看到的大部分操作,包括视图或layer的移动、旋转、缩放,不需要重绘。最好的图片动画方式是创建图片的视图或layer,然后使用Core Annimation去实现任何动画。这种方法能避免调用-drawRect: ,并因此调用CGContextDrawImage or UIImage/-drawInRect:。
用一个简单的例子说明下,假设你想在绘制一个精灵围绕z轴旋转垂直于屏幕。一种方法是每个动画步骤在视图的-drawRect:方法中当前的矩阵变换(CGContextRotateCTM)应用旋转矩阵并且重绘图片(CGContextDrawImage)。然而,一个更高效的方法是设置的CALayer的contents属性为这个图片,然后使用动画层的transform属性去完成旋转动画。
如果你在一个图像上有独立的移动的组件,那么你应该分解到独立的视图或layers,单独的执行动画。例如,如果你绘制一个可拖动的图像,当处理移动的 时候,你应该放在独立的层,然后移动这个层,而不是invalidate整个图像视图。
有些情况(不是大多数)CALayer和Core Animation不起作用。对这些情况,记住CGContextDrawImage和UIImage/-drawInRect: 必须花费大量的时间去解压或重新采样这个图片,因为图片不会被缓存到layer tree中。
警告:调用像 CGContextDrawImage 和 UIImage/-drawInRect: 绘制图像是要付出特别昂贵的代价,当他们必须解压或缩放图片显示的时候。
1.在UIImageView中设置一个UIImage作为layer的内容
// 这也会设置view的contentScaleFactor给图片的scale factor
imageView.image = image;
2. 视图z周的旋转动画
- (void)rotateView:(UIView *)view toAngle:(float)angle {
[UIView beginAnimations:nil context:nil];
[view setTransform:CGAffineTransformMakeRotation(angle)];
[UIView commitAnimations];
}
3. 调整UIImage尺寸,结果可以缓存在image array中
- (UIImage*)resizeImage:(UIImage*)image toWidth:(NSInteger)width height:(NSInteger)height
{
// Create a graphics context with the target size
// On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
// On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
CGSize size = CGSizeMake(width, height);
if (NULL != UIGraphicsBeginImageContextWithOptions)
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
else
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
// Flip the context because UIKit coordinate system is upside down to Quartz coordinate system
CGContextTranslateCTM(context, 0.0, height);
CGContextScaleCTM(context, 1.0, -1.0);
// Draw the original image to the context
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextDrawImage(context, CGRectMake(0.0, 0.0, width, height), image.CGImage);
// Retrieve the UIImage from the current context
UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageOut;
}