2010-02-21 19 views
14

Sto cercando un metodo per aggiungere gradualmente il bordo sbiadito o forse sfocato (non so esattamente come denominare questo effetto) a UIView arbitrario. Non ho bisogno di effetti animati, ho bisogno di effetti statici, ad esempio il mio bordo UITableView è parzialmente trasparente. Ho fatto l'esempio:Bordo UIView con effetto dissolvenza o sfocatura

enter image description here

Così si può vedere quello che sto cercando di fare.

Qualcuno può aiutarmi?

+0

Tutte le idee? Per favore... – iKiR

risposta

16

ho trovato una soluzione - ho useed maschera proprietà di CALayer:

CALayer *viewLayer = [back layer]; 
CALayer* maskCompoudLayer = [CALayer layer]; 

maskLayer.bounds = viewLayer.bounds; 

[maskLayer setPosition:CGPointMake(160, CGRectGetHeight(maskCompoudLayer.frame)/2.0)];  

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef context = CGBitmapContextCreate (NULL, 320, 480, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);  

CGFloat colors[] = { 
     0.5, 0.5, 0.5, 0.0, //BLACK 
     0.0, 0.0, 0.0, 1.0, //BLACK 
};  

CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, sizeof(colors)/(sizeof(colors[0])*4));  
CGColorSpaceRelease(colorSpace);  

NSUInteger gradientH = 20; 
NSUInteger gradientHPos = 0; 

CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0].CGColor); 
CGContextFillRect(context, CGRectMake(0, gradientHPos + gradientH, CGRectGetWidth(maskLayer.frame), CGRectGetHeight(maskLayer.frame)));  

CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.0].CGColor); 
CGContextFillRect(context, CGRectMake(0, 0, 320, gradientHPos)); 

CGContextDrawLinearGradient(context, gradient, CGPointMake(160, gradientHPos), CGPointMake(160, gradientHPos + gradientH), 0);  
CGGradientRelease(gradient);  

CGImageRef contextImage = CGBitmapContextCreateImage(context); 
CGContextRelease(context);  

[maskLayer setContents:(id)contextImage]; 

CGImageRelease (contextImage); 

viewLayer.masksToBounds = YES; 
viewLayer.mask = maskCompoudLayer; 

Usando questo codice che ho UITableView con dissolvenza bordo

+0

Potresti per favore approfondire come questo è stato effettivamente combinato con UITableView? Grazie! – jowie

+7

Mi piacerebbe anche sapere come lo hai usato in modo specifico. Potresti pubblicare un blocco di codice più completo? Cos'è MaskLayer? Cos'è il back layer? – DoctorG

+6

Ciao a tutti, gente del 2011. Sono qui dal 2012, e voglio ancora conoscere i dettagli .. Quindi, credo che aggiungerò una risposta su quello che mi è venuto in mente. – Mazyod

3

Si potrebbe provare a posizionare un file PNG semitrasparente sul fondo di UITableView.

+3

Sì, ma in questo caso dovrò avere PNG diversi per sfondi diversi, vorrei trovare una soluzione universale – iKiR

10

Dirò questo primo, la risposta di iKiR era più che abbastanza per me. Ho copiato il codice così com'è e, con poca esperienza da parte mia, sono riuscito a farlo funzionare senza sforzo (su un UITableView).

  1. Creare una nuova sottoclasse UIView, lo chiamerò MaskingView
  2. importazione QuartzCore quadro!
  3. Incollare il codice qui sotto nella init. (e/o initWithFrame: a seconda del caso)
  4. Aggiungere la vista in cui si desidera applicare la sfumatura di opacità all'interno di MaskingView. (In Interface Builder, user Editor -> Incorpora in -> Visualizza. Quindi, scegli la classe della nuova superview come MaskingView)
  5. Dai il massimo a IKiR, perché non ho idea di come funzioni il codice, ma semplicemente funziona!

NOTE:

  • Sto sviluppando un'applicazione universale, e il codice qui sotto funziona in quanto è su entrambi i dispositivi! (iPhone/iPad)
  • Quando si utilizza Incorpora In -> UIView, la nuova vista sarà leggermente più grande della visualizzazione secondaria. Devi adattarlo esattamente alla sottoview. Ma, prima di ridimensionarlo, assicurati di deselezionare le visualizzazioni secondarie autoresize.

Il Codice:

CALayer *viewLayer = [self layer]; 
CALayer* maskLayer = [CALayer layer]; 

maskLayer.bounds = viewLayer.bounds; 

[maskLayer setPosition:CGPointMake(CGRectGetWidth(viewLayer.frame)/2.0, CGRectGetHeight(viewLayer.frame)/2.0)];  

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef context = CGBitmapContextCreate (NULL, viewLayer.bounds.size.width, viewLayer.bounds.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);  

CGFloat colors[] = { 
    0.5, 0.5, 0.5, 0.0, //BLACK 
    0.0, 0.0, 0.0, 1.0, //BLACK 
};  

CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, sizeof(colors)/(sizeof(colors[0])*4));  
CGColorSpaceRelease(colorSpace);  

NSUInteger gradientH = 20; 
NSUInteger gradientHPos = 0; 

CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0].CGColor); 
CGContextFillRect(context, CGRectMake(0, gradientHPos + gradientH, CGRectGetWidth(maskLayer.frame), CGRectGetHeight(maskLayer.frame)));  

CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.0].CGColor); 
CGContextFillRect(context, CGRectMake(0, 0, 320, gradientHPos)); 

CGContextDrawLinearGradient(context, gradient, CGPointMake(160, gradientHPos), CGPointMake(160, gradientHPos + gradientH), 0);  
CGGradientRelease(gradient);  

CGImageRef contextImage = CGBitmapContextCreateImage(context); 
CGContextRelease(context);  

[maskLayer setContents:(__bridge id)contextImage]; 

CGImageRelease (contextImage); 

viewLayer.masksToBounds = YES; 
viewLayer.mask = maskLayer; 
3

C'è un tutorial in Cocoanetics che lo fa cosa esatta.

+0

Funziona solo se stai usando uno sfondo colorato statico, non funzionerà con gli sfondi delle immagini dato che questo tutorial aggiunge una sfumatura colorata sopra la vista che vuoi "sfumare" – Hjalmar

1

Ecco la risposta di iKiR e Mazyod, tradotta in Xamarin.iOS (Monotouch). Si noti che non c'è bisogno di disegnare rettangoli prima e dopo il gradiente se si passa le bandiere retto rispetto al metodo DrawLinearGradient:

var vl = myView.Layer; 
var l = new CALayer(); 
l.Frame = new RectangleF(vl.Frame.Width/2, vl.Frame.Height/2, 
      vl.Frame.Width, vl.Frame.Height) ; 
var cs = CGColorSpace.CreateDeviceRGB(); 
var g = new CGBitmapContext (null, 
      (int) vl.Bounds.Size.Width, (int)vl.Bounds.Size.Height, 
      8, 0, cs, CGImageAlphaInfo.PremultipliedLast); 
var colors = new CGColor[] { UIColor.FromWhiteAlpha(1, 0).CGColor, 
      UIColor.FromWhiteAlpha(1, 1f).CGColor }; 
var grad = new CGGradient (cs, colors, new float[] { 0f, 1f }); 
int gradH = 20, gradHPos = 0; 
g.DrawLinearGradient (grad, 
      new PointF (l.Frame.Width/2, gradHPos), new PointF (l.Frame.Width/2, gradHPos + gradH), 
      CGGradientDrawingOptions.DrawsBeforeStartLocation | CGGradientDrawingOptions.DrawsAfterEndLocation); 
grad.Dispose(); 

l.Contents = g.ToImage(); 
g.Dispose(); 

vl.Mask = l; 
vl.MasksToBounds = true; 
Problemi correlati