2009-05-14 16 views
15

Moje oryginalne pytanie:UIView: jak wykonać nieniszczący rysunek?

tworzę prosty rysunek aplikacji i muszą być w stanie narysować na istniejącej, uprzednio sporządzony zawartości w moim drawRect. Jaki jest właściwy sposób na wciągnięcie istniejącej zawartości bez całkowitego jej zastąpienia?

Na podstawie odpowiedzi otrzymanych tutaj i gdzie indziej, oto oferta.

  1. Należy być przygotowanym na przerysowanie cały prostokąt gdy drawRect jest tzw.

  2. Ty nie może zapobiec zawartość przed przypadkowym usunięciem, wykonując następujące czynności:

    [self setClearsContextBeforeDrawing: NO];

    to jedynie wskazówkę do silnika graficznego, że nie ma sensu w to pre-jasne dla ciebie, ponieważ prawdopodobnie będziesz musiał ponownie narysować cały obszar. Może to uniemożliwić automatyczne usunięcie twojego widoku, , ale nie możesz na nim polegać.

  3. Aby narysować na górze widoku bez wymazywanie, czy rysunek do kontekstu bitmapy off-screen (który nigdy nie jest usuwany przez system). Następnie w swojej drawRect, skopiować z tego bufora wyłączonym ekranie widoku .

przykład:

- (id) initWithCoder: (NSCoder*) coder {  
    if (self = [super initWithCoder: coder]) { 
     self.backgroundColor = [UIColor clearColor]; 
     CGSize size = self.frame.size; 
     drawingContext = [self createDrawingBufferContext: size]; 
    } 

    return self; 
} 

- (CGContextRef) createOffscreenContext: (CGSize) size { 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, size.width*4, colorSpace, kCGImageAlphaPremultipliedLast); 
    CGColorSpaceRelease(colorSpace); 

    CGContextTranslateCTM(context, 0, size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 
    return context; 
} 


- (void)drawRect:(CGRect) rect {  
    UIGraphicsPushContext(drawingContext); 
    CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext); 
    UIImage *uiImage = [[UIImage alloc] initWithCGImage:cgImage]; 
    UIGraphicsPopContext(); 
    CGImageRelease(cgImage); 
    [uiImage drawInRect: rect]; 
    [uiImage release]; 
} 

Do zrobienia: ktoś może zoptymalizować drawRect tak, że tylko (zwykle małe) zmodyfikowany region prostokąt jest używany do kopiowania?

Odpowiedz

5

Dosyć często rysuje się wszystko na ekranie poza ekranem i po prostu wyświetla ten obraz podczas rysowania ekranu. Możesz przeczytać: Creating a Bitmap Graphics Context.

+0

Hmm, to odniesienie wydaje się być C-Code. Kiedy próbowałem dodać go do mojej klasy Objective-C, symulator ulega awarii (niestety z debuggerem). –

+0

O ile wiem, jest to Quartz, obsługiwany przez iPhone'a. Prawdopodobnie zrobiłeś coś złego ... Chcesz nam pokazać, co zrobiłeś? –

+0

Pewnie. Mój drawRect() wywołuje kod "flag drawing" z przytoczonego przykładu. Mam kopię/wkleiłem na adres: http://pastebin.com/m68230dcd Dziękujemy za poświęcony czas. –

0

Wygląda to na lepszą metodę niż używam. Oznacza to, że w przypadku dotknięć robię kopię widoku, który ma zostać zaktualizowany. Następnie w drawRect biorę ten obraz i rysuję go do widoku, a mój drugi widok zmienia się w tym samym czasie.

Ale wydaje się to nieefektywne, ale jedyny sposób, w jaki wymyśliłem, jak to zrobić.

1

optymalizacji drawRect

Spróbuj tego:

- (void)drawRect:(CGRect)rect { 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGImageRef cgImage = CGBitmapContextCreateImage(drawingContext); 
    CGContextClipToRect(context, rect); 
    CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), cgImage); 
    CGImageRelease(cgImage); 
} 

Po tym należy również skomentować te linie w kodzie:

//CGContextTranslateCTM(context, 0, size.height); 
//CGContextScaleCTM(context, 1.0, -1.0); 

stworzył także a separate question aby mieć pewność, że jest to optymalny sposób.

0

Zapobiega widoku przed skasowaniem przed drawRect odbywa:

[self.layer setNeedsDisplay]; 

Również uważam, że lepiej jest zrobić wszystko rysunek w metodzie drawRect (chyba że masz dobry powód, aby nie). Rysowanie poza ekranem i przenoszenie zabiera więcej czasu i zwiększa złożoność, a następnie rysuje wszystko raz.