在CALayer - 1中我们了解到setNeedsDisplay这个方法,而其实UIView 和 CALayer都是存在这个方法的!我们来看看这个方法:无论在UIView 或者 CALayer上,都是提及这个方法的作用:刷新,重绘 视图内容contents
来看看简单的例子:
UIView:
头文件:
#import <UIKit/UIKit.h>
@interface LBSetNeedsDisplayUIViewViewController : UIViewController
@end
@interface LBNeedsDisView : UIView
@property (nonatomic, assign) BOOL hasRandomColor;
@end
实现文件:
#import "UIColor+RandomColor.h"
#import "LBSetNeedsDisplayUIViewViewController.h"
@interface LBSetNeedsDisplayUIViewViewController ()
@property (nonatomic, strong) LBNeedsDisView* needsDisView;
@end
@implementation LBSetNeedsDisplayUIViewViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.needsDisView = [[LBNeedsDisView alloc] init];
[self.needsDisView setFrame:CGRectMake(0, 0, 100, 100)];
[self.needsDisView setCenter:self.view.center];
[self.view addSubview:self.needsDisView];
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(0, 0, 50, 50)];
[button setCenter:CGPointMake(self.view.center.x, button.center.y)];
[button setBackgroundColor:[UIColor yellowColor]];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)buttonClicked:(id)sender
{
self.needsDisView.hasRandomColor = YES;
[self.needsDisView setNeedsDisplay];
}
@end
#pragma LBNeedsDisView
@implementation LBNeedsDisView
- (id)init
{
self = [super init];
if (self)
{
_hasRandomColor = NO;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
if (_hasRandomColor)
{
self.backgroundColor = [UIColor randomColor]; //随机刷新颜色
}
}
@end
同理地,CALayer:
头文件:
#import <UIKit/UIKit.h>
@interface LBSetNeedsDisplayCALayerViewController : UIViewController
@end
@interface LBNeedsDisplayLayer : CALayer
@property (nonatomic, assign) BOOL hasRandomColor;
@end
实现文件:
#import "UIColor+RandomColor.h"
#import "LBSetNeedsDisplayCALayerViewController.h"
@interface LBSetNeedsDisplayCALayerViewController ()
@property (nonatomic, strong) LBNeedsDisplayLayer* layer;
@end
@implementation LBSetNeedsDisplayCALayerViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.layer = [LBNeedsDisplayLayer layer];
self.layer.backgroundColor = [UIColor brownColor].CGColor;
self.layer.bounds = CGRectMake(100, 100, 200, 150);
[self.view.layer addSublayer:self.layer];
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(0, 0, 50, 50)];
[button setCenter:CGPointMake(self.view.center.x, button.center.y)];
[button setBackgroundColor:[UIColor yellowColor]];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)buttonClicked:(id)sender
{
self.layer.hasRandomColor = YES;
[self.layer setNeedsDisplay];
}
@end
@implementation LBNeedsDisplayLayer
- (id)init
{
self = [super init];
if (self)
{
_hasRandomColor = NO;
}
return self;
}
- (void)drawInContext:(CGContextRef)ctx
{
[super drawInContext:ctx];
if (_hasRandomColor)
{
self.backgroundColor = [UIColor randomColor].CGColor;
}
}
@end
实现方式几乎一样哈!!
这里提几点:
1.UIView的drawRect在自定义UIView的子类初始化重载(重写)的同时也会调用,但是CALayer不会
2.两者通过setNeedsDisplay都会调用对应的drawRect: 和 DrawInContext: , 贴切刷新的意思
3.两者的rect如果是zero , 都不能响应这个方法,应该没有刷新和重绘的必要,两者都有局部重绘的方法
4.CALayer如果不用drawInContext:而采用代理实现的话,setNeedsDisplay是响应代理的实现方法:drawLayer: inContext:
5.线程上是异步执行,不会阻塞线程,并且在runloop最后一个阶段执行(有待验证)
非常常见的用法,用在set方法里面,每次调用set属性方法的时候及时刷新:
更新属性后,调用setNeedsDisplay
- (void)setType:(JSBubbleMessageType)newType
{
type = newType;
[self setNeedsDisplay];
}
在drawRect:方法里面相应地判断:
- (void)drawRect:(CGRect)frame
{
[super drawRect:frame];
if (self.mediaType == JSBubbleMediaTypeText)
{
//do something.
}
}
上面两个例子就是这样的形式来编写的
参考:http://www.cnblogs.com/ydhliphonedev/archive/2011/08/12/2135627.html