Ios 如何提高drawRect的性能?
在我的应用程序中,我通过将UIView子类化来创建网格视图。如果用户触摸网格的一个单元格,它会在许多不同的状态之间切换,例如“开”或“关”,并相应地改变颜色。因此,当触摸单元格时,我会调用Ios 如何提高drawRect的性能?,ios,objective-c,drawing,drawrect,Ios,Objective C,Drawing,Drawrect,在我的应用程序中,我通过将UIView子类化来创建网格视图。如果用户触摸网格的一个单元格,它会在许多不同的状态之间切换,例如“开”或“关”,并相应地改变颜色。因此,当触摸单元格时,我会调用setNeedsDisplay刷新视图 在我的新iphone5s上效果很好,但在iphone4上性能很差——我的整个应用程序都冻结了,音频断断续续等。有更好的方法吗?如何提高性能 /** * Draw rect */ -(void)drawRect:(CGRect)rect { _cellWidt
setNeedsDisplay
刷新视图
在我的新iphone5s上效果很好,但在iphone4上性能很差——我的整个应用程序都冻结了,音频断断续续等。有更好的方法吗?如何提高性能
/**
* Draw rect
*/
-(void)drawRect:(CGRect)rect
{
_cellWidth = _frameWidth / _gridSizeX;
_cellHeight = _frameHeight / _gridSizeY;
int firstCellY = _frameHeight - _cellHeight;
for(int x = 0; x < _gridSizeX; x++) {
for(int y = 0; y < _gridSizeY; y++) {
CGRect rect = CGRectMake(x * _cellWidth, firstCellY - (y * _cellHeight), _cellWidth, _cellHeight);
UIColor *strokeColor = [UIColor grid];
UIColor *fillColor;
if(currentBeat != x) {
switch(mCells[x][y]) {
case OFF:
//bar lines
if(x % 4 == 0) {
fillColor = [UIColor bgBar];
}
//octave lines
else if(scaleLength > 0 && (y % scaleLength == 0 || y == _gridSizeY-1)) {
fillColor = [UIColor bgOctave];
}
else {
fillColor = [UIColor bgMain];
}
break;
case ON:
fillColor = [UIColor cellOn];
break;
case ON_EXTEND:
fillColor = [UIColor cellOnExtend];
break;
case LOCKED:
fillColor = [UIColor cellLocked];
break;
case LOCKED_EXTEND:
fillColor = [UIColor cellLockedExtend];
break;
default:
break;
}
}
else {
switch (mCells[x][y]) {
case OFF:
if(_playing) {
fillColor = [UIColor bgMainHL];
}
else {
fillColor = [UIColor bgBar];
}
break;
case ON:
if(_playing) {
fillColor = [UIColor cellOnHL];
}
else {
fillColor = [UIColor cellOn];
}
break;
case ON_EXTEND:
fillColor = [UIColor cellOnExtendHL];
break;
case LOCKED:
if(_playing) {
fillColor = [UIColor cellLockedHL];
}
else {
fillColor = [UIColor cellLocked];
}
break;
case LOCKED_EXTEND:
fillColor = [UIColor cellLockedExtendHL];
break;
default:
break;
}
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, fillColor.CGColor);
CGContextSetStrokeColorWithColor(context, strokeColor.CGColor);
CGContextFillRect(context, rect);
CGContextStrokeRect(context, rect);
}
}
}
/**
* Touch events
*/
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self handleTouches:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self handleTouches:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self handleTouches:touches withEvent:event];
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self handleTouches:touches withEvent:event];
}
/**
* Handle touches
*/
-(void)handleTouches:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self];
//Find column and row
int col = (int) (location.x / _cellWidth);
int row = (int) _gridSizeY - (location.y / _cellHeight);
//Only redraw view when row and column changed, so doesn't redraw every touch that's registered
if([touch phase] == UITouchPhaseBegan || (touchBeganCol != col || touchBeganRow != row)) {
[self.delegate mViewTouchEventWithTouch:touch andRow:row andColumn:col];
[self setNeedsDisplay];
touchBeganCol = col;
touchBeganRow = row;
NSLog(@"redraw");
}
else if([touch phase] == UITouchPhaseEnded || [touch phase] == UITouchPhaseCancelled) {
[self.delegate mViewTouchEventWithTouch:touch andRow:row andColumn:col];
[self setNeedsDisplay];
touchBeganCol = 99999;
touchBeganRow = 99999;
NSLog(@"redraw");
}
}
/**
*绘制矩形
*/
-(void)drawRect:(CGRect)rect
{
_cellWidth=\u frameWidth/\u gridSizeX;
_cellHeight=\u frameHeight/\u gridSizeY;
int firstCellY=\u frameHeight-\u cellHeight;
对于(int x=0;x<\u gridSizeX;x++){
对于(int y=0;y<\u gridSizeY;y++){
CGRect rect=CGRectMake(x*_cellWidth,firstCellY-(y*_cellHeight),_cellWidth,_cellHeight);
UIColor*strokeColor=[UIColor网格];
UIColor*fillColor;
如果(当前拍数!=x){
开关(mCells[x][y]){
案例:
//条线
如果(x%4==0){
fillColor=[UIColor bgBar];
}
//倍频程线
else if(scaleLength>0&(y%scaleLength==0 | | y==U gridSizeY-1)){
fillColor=[UIColor bg倍频程];
}
否则{
fillColor=[UIColor bgMain];
}
打破
案件涉及:
fillColor=[UIColor-cellOn];
打破
(扩展)个案:
fillColor=[UIColor cellOnExtend];
打破
案件锁定:
fillColor=[UIColor cellLocked];
打破
案例锁定\u扩展:
fillColor=[UIColor cellLockedExtend];
打破
违约:
打破
}
}
否则{
开关(mCells[x][y]){
案例:
如果(正在播放){
fillColor=[UIColor bgMainHL];
}
否则{
fillColor=[UIColor bgBar];
}
打破
案件涉及:
如果(正在播放){
fillColor=[UIColor cellOnHL];
}
否则{
fillColor=[UIColor-cellOn];
}
打破
(扩展)个案:
fillColor=[UIColor cellOnExtendHL];
打破
案件锁定:
如果(正在播放){
fillColor=[UIColor cellLockedHL];
}
否则{
fillColor=[UIColor cellLocked];
}
打破
案例锁定\u扩展:
fillColor=[UIColor cellLockedExtendHL];
打破
违约:
打破
}
}
CGContextRef context=UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(上下文,fillColor.CGColor);
CGContextSetStrokeColorWithColor(上下文,strokeColor.CGColor);
CGContextFillRect(上下文,rect);
CGContextStrokeRect(上下文,rect);
}
}
}
/**
*触摸事件
*/
-(无效)触摸开始:(NSSet*)触摸事件:(UIEvent*)事件
{
[自行触摸:触摸事件:事件];
}
-(无效)触摸移动:(NSSet*)触摸事件:(UIEvent*)事件
{
[自行触摸:触摸事件:事件];
}
-(void)touchesend:(NSSet*)toucheevent:(UIEvent*)event
{
[自行触摸:触摸事件:事件];
}
-(无效)触控取消:(NSSet*)触控事件:(UIEvent*)事件
{
[自行触摸:触摸事件:事件];
}
/**
*把手接触
*/
-(无效)手触:(NSSet*)接触事件:(UIEvent*)事件
{
UITouch*touch=[[event AllTouchs]anyObject];
CGPoint位置=[触摸位置查看:自];
//查找列和行
int col=(int)(location.x/_cellWidth);
int row=(int)_gridSizeY-(location.y/_cellHeight);
//只有在行和列发生更改时才重新绘制视图,因此不会重新绘制已注册的每个触摸
如果([touch phase]==UITouchPhaseBegan | | |(touchBeganCol!=col | | | touchBeganRow!=row)){
[self.delegate mViewTouchEventWithTouch:touch andRow:row:row和coln:col];
[自我设置需要显示];
touchBeganCol=col;
touchBeganRow=行;
NSLog(“重新绘制”);
}
否则如果([触摸阶段]==UITouchPhase已取消| |[触摸阶段]==UITouchPhase已取消){
[self.delegate mViewTouchEventWithTouch:touch andRow:row:row和coln:col];
[自我设置需要显示];
touchBeganCol=99999;
touchBeganRow=99999;
NSLog(“重新绘制”);
}
}
有几件事可以帮上忙:根据经验,您应该尽量避免在图形代码中进行对象分配,因为这非常昂贵。在代码中,下一行可以移到double for循环之外,只需重用变量即可
UIColor *strokeColor = [UIColor grid];
UIColor *fillColor;
为了扩展前面的注释,这是我不确定的,甚至像[UIColor bgBar]这样的调用也可能实例化对象。我通常有类变量,比如bgBarColor,已经设置了合适的颜色
另一个有用的提示是使需要为红色的rect无效
/**
* Draw layers
*/
-(void)drawLayers
{
for(CellLayer *layer in layerArray) {
[layer removeFromSuperlayer];
}
[layerArray removeAllObjects];
_cellWidth = _frameWidth / _gridSizeX;
_cellHeight = _frameHeight / _gridSizeY;
int firstCellY = _frameHeight - _cellHeight;
UIColor *strokeColor = [UIColor grid];
for(int x = 0; x < _gridSizeX; x++) {
for(int y = 0; y < _gridSizeY; y++) {
CellLayer *cellLayer = [CellLayer layer];
cellLayer.frame = CGRectMake(x * _cellWidth, firstCellY - (y * _cellHeight), _cellWidth, _cellHeight);
cellLayer.backgroundColor = [self getColourForState:mCells[x][y] andX:x andY:y].CGColor;
cellLayer.borderColor = strokeColor.CGColor;
cellLayer.borderWidth = 0.5;
cellLayer.col = x;
cellLayer.row = y;
cellLayer.state = mCells[x][y];
[layerArray addObject:cellLayer];
[self.layer addSublayer:cellLayer];
}
}
}
- (void)redrawChangedCells
{
[CATransaction setDisableActions:YES];
[[layerArray copy] enumerateObjectsUsingBlock:^(CellLayer *layer, NSUInteger idx, BOOL *stop) {
if(mCells[layer.col][layer.row] != layer.state) {
layer.backgroundColor = [self getColourForState:mCells[layer.col][layer.row] andX:layer.col andY:layer.row].CGColor;
layer.state = mCells[layer.col][layer.row];
[self updateLayerArrayWithLayer:layer andIndex:idx];
}
}];
}