2011-01-16 16 views
1

Ich habe eine UIView, wo ich die Hintergrundfarbe in der init-Methode deaktivieren. Ich zeichne dann eine blaue Linie zwischen 2 Punkten in drawRect. Der erste Punkt ist die allererste Berührung der Ansicht und der zweite Punkt wird geändert, wenn touchesMoved aufgerufen wird.QuartzCore Leistung auf clear UIView

So, dass ein Ende der Linie fixiert ist, und das andere Ende bewegt sich mit dem Finger des Benutzers. Wenn die Hintergrundfarbe jedoch klar ist, hat die Linie eine ziemlich große Verzögerung und springt (ist nicht glatt).

Wenn ich die Hintergrundfarbe zu schwarz ändere (nur die Setbackgroundcolor Linie auskommentieren), dann ist die Bewegung viel glatter und es sieht gut aus, abgesehen davon, dass Sie die Ansichten dahinter nicht sehen können.

Wie kann ich dieses Problem lösen? (auf dem iPad, ich habe nur den Simulator, und habe derzeit keinen Zugriff auf ein Gerät) Damit die Leistung ist glatt, aber der Hintergrund ist klar, so dass Sie die Hintergrundansichten sehen können.

-(id) initWithFrame:(CGRect)frame { 
    if (self = [super initWithFrame:frame]) { 
     //self.backgroundColor = [UIColor clearColor]; 
    } 
    return self; 
} 

-(void) drawRect:(CGRect)rect { 
if (!CGPointEqualToPoint(touchPoint, CGPointZero)) { 
    if (touchEnded) { 
     CGContextRef context = UIGraphicsGetCurrentContext(); 
     CGContextClearRect(context, rect); 
    } else { 

CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextClearRect(context, rect); 
    CGContextSetLineWidth(context, 3.0f); 
    CGFloat blue[4] = {0.0f, 0.659f, 1.0f, 1.0f}; 
    CGContextSetAllowsAntialiasing(context, YES); 
    CGContextSetStrokeColor(context, blue); 
    CGContextMoveToPoint(context, startPoint.x, startPoint.y); 
    CGContextAddLineToPoint(context, touchPoint.x, touchPoint.y); 
    CGContextStrokePath(context); 

    CGContextSetFillColor(context, blue); 

    CGContextFillEllipseInRect(context, CGRectMakeForSizeAroundCenter(CGSizeMake(10, 10), touchPoint)); 
    CGContextFillEllipseInRect(context, CGRectMakeForSizeAroundCenter(CGSizeMake(10, 10), startPoint)); 
    } 
    } 
} 



-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    self.touchEnded = NO; 
    if ([[touches allObjects] count] > 0) 
     startPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self]; 
     touchPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self]; 
    [self setNeedsDisplay]; 
} 

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    self.touchEnded = NO; 
    if ([[touches allObjects] count] > 0) 
     touchPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self]; 
    [self setNeedsDisplay]; 
} 
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    self.touchEnded = YES; 
    [self setNeedsDisplay]; 
    [self removeFromSuperview]; 
} 
- (void)dealloc { 
    [super dealloc]; 
} 

Antwort

1

Zunächst sollten Sie die Leistung auf einem Gerät statt im Simulator testen. Die meisten Grafik-bezogenen Sachen funktionieren sehr unterschiedlich im Simulator, einige sind viel schneller und einige, überraschend, viel langsamer.

Das heißt, wenn ein transparenter Hintergrund ein Leistungsproblem auf einem Gerät sein wird, ist es wahrscheinlich, dass Sie zu viele Pixel mit CGContextClearRect() füllen. Ich kann mich zwei Lösungen aus der Spitze von meinem Kopf:

  • In touchesBegan:withEvent: Sie einen Schnappschuss der zugrunde liegenden Ansicht machen (s) CALayer die renderInContext:-Methode und die Momentaufnahme als Hintergrund ziehen, anstatt sie zu löschen. Auf diese Weise können Sie die Ansicht opak lassen und somit Zeit sparen, wenn Sie die Ansicht mit Ansichten darunter zusammenstellen.
  • Sie können einen CALayer mit einer Höhe von einem Punkt erstellen, der eine Linie darstellt, und ihn in touchesMoved:withEvent: so transformieren, dass sich seine Enden in den richtigen Positionen befinden. Dasselbe gilt für Punkte, die die Linienenden darstellen (CAShapeLayer ist dafür großartig). Es wird einige hässliche Trigonometrie geben, aber die Leistung wird ausgezeichnet sein.