2010-02-21 1 views
14

Я ищу способ добавить постепенное увядание или, возможно, размытую границу (я точно не знаю, как назвать этот эффект) произвольному UIView. Мне не нужен анимированный эффект, мне нужен статический эффект, например, моя граница UITableView является частично прозрачной. Я сделал пример:Граница UIView с эффектом затухания или размытия

enter image description here

Таким образом, вы можете увидеть, что я пытаюсь сделать.

Может ли кто-нибудь мне помочь?

+0

Любые идеи? Пожалуйста... – iKiR

ответ

16

Я нашел решение - я useed 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; 

Используя этот код у меня есть UITableView с выцветания границу

+0

Не могли бы вы рассказать о том, как это было в целом объединено с UITableView? Благодаря! – jowie

+7

Я также хотел бы знать, как вы это использовали. Не могли бы вы разместить более полный блок кода? Что такое maskLayer? Что такое задний слой? – DoctorG

+6

Привет, люди с 2011 года. Я здесь с 2012 года и все еще хочу узнать подробности. Итак, я думаю, я добавлю ответ на то, что я придумал. – Mazyod

3

Возможно, вы попытаетесь разместить полупрозрачный PNG-файл в нижней части UITableView.

+3

Да, но в этом случае мне придется иметь разные PNG для разных фонов, я бы хотел найти универсальное решение. – iKiR

10

Я скажу это первый, ответ ИКИР был более чем достаточно для меня. Я скопировал код так, как есть, и с небольшим опытом со своей стороны я смог заставить его работать без усилий (на UITableView).

  1. Создать новый UIView подкласс, я буду называть его MaskingView
  2. импорт QuartzCore рамки!
  3. Вставьте код ниже в init. (initWithCoder: и/или)
  4. Добавьте представление, в котором вы хотите применить непрозрачность, в пределах MaskingView. (В интерфейсе Builder, Редактор пользователя -> Вставить In -> View. Затем выберите класс нового супервизора как MaskingView)
  5. Отдайте должное iKiR, потому что я не знаю, как работает код, но это просто работает!

ПРИМЕЧАНИЯ:

  • Я занимаюсь разработкой универсального приложения, а ниже код работает как на обоих устройствах! (iPhone/iPad)
  • При использовании Embed In -> UIView новый вид будет немного больше, чем subview. Вы должны сделать так, чтобы он соответствовал подзону. Но прежде, чем изменить размер, убедитесь, что вы сняли флажок autoresize subviews.

Кодекс:

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

Там в учебник по Cocoanetics, что делает это точная вещь.

+0

Это работает только в том случае, если вы используете статический цветной фон, не работает на фоновых изображениях, так как в этом руководстве добавлен цветной градиент над представлением, которое вы хотите «погасить», – Hjalmar

1

Вот ответ iKiR и Mazyod, переведенный на Xamarin.iOS (Monotouch). Обратите внимание, что нет необходимости рисовать прямоугольники до и после того, как градиент, если вы просто передать правильные флаги к методу 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;