2012-06-13 5 views
6

Ho un'applicazione iPhone e ho bisogno di attuare il seguente metodo:disegno con colore chiaro UIView (tagliando un foro) nel metodo statico

+(UITextView *)textView:(UITextView *) withCuttedRect:(CGRect)r 

Questo metodo deve tagliare (riempire con [UIColor clearColor]) rect r da UITextView e restituire l'oggetto UITextView.

L'utente vedrà la vista dietro UITextView dai fori tagliati.

Come può essere fatto?

+0

Forse Dovrei usare quartzcore ed è il metodo di filtri 'setBackground'? – user1385666

risposta

5

Quando volete avere qualcosa di simile:

+(UITextView *)textView:(UITextView *)textView withCuttedRect:(CGRect)r { 
} 

in realtà si può semplicemente accedere al secondo livello del TextView dall'animazione core con

textView.layer 

Quello che allora possibile per è impostato una maschera per ritaglio. Queste maschere funzionano in questo modo: in genere si disegna una forma nera, che rimane invariata, il resto verrà ritagliato (ok, in realtà puoi anche fare alcune cose sul canale alfa, ma grosso modo è così).

Quindi è necessario un rettangolo nero come maschera, con un rettangolo all'interno del rettangolo che è gratuito. per questo si può approssimativamente fare

CAShapeLayer *mask = [[CAShapeLayer alloc] init]; 
mask.frame = self.textView.layer.bounds; 
CGRect biggerRect = CGRectMake(mask.frame.origin.x, mask.frame.origin.y, mask.frame.size.width, mask.frame.size.height); 
CGRect smallerRect = CGRectMake(50.0f, 50.0f, 10.0f, 10.0f); 

UIBezierPath *maskPath = [UIBezierPath bezierPath]; 
[maskPath moveToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMinY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMaxY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(biggerRect), CGRectGetMaxY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(biggerRect), CGRectGetMinY(biggerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(biggerRect), CGRectGetMinY(biggerRect))]; 

[maskPath moveToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMinY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMaxY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(smallerRect), CGRectGetMaxY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMaxX(smallerRect), CGRectGetMinY(smallerRect))]; 
[maskPath addLineToPoint:CGPointMake(CGRectGetMinX(smallerRect), CGRectGetMinY(smallerRect))]; 

mask.path = maskPath.CGPath; 
[mask setFillRule:kCAFillRuleEvenOdd]; 
mask.fillColor = [[UIColor blackColor] CGColor]; 
self.textView.layer.mask = mask; 

Il codice di cui sopra è in disuso anche da Crop a CAShapeLayer retrieving the external path

L'idea per questo che il riempimento funziona in questo modo è ben spiegato nel Quartz 2D Programming Guide nella sezione "Riempimento di un percorso di"

+0

Bello! E solo una nota, per fare lo stesso con un 'CGContext', tu aggiungi il percorso come hai fatto tu, e poi lo riempi con' CGContextEOFillPath (context) '. :) Dove EO significa anche strano, da non confondere con EndOfFile (che è il modo in cui esegue la scansione per me). –

+1

Qui puoi tagliare alcune righe di codice usando '[UIBezierPath bezierPathWithRect: biggerRect]' invece del semplice '[UIBezierPath bezierPath]'. Questo inizializzerà il maskPath con il più grandeRect pre-aggiunto. In questo modo è sufficiente utilizzare moveToPoint: e addLineToPoint: per aggiungere il secondo rect. –