Граница UIView с эффектом затухания или размытия

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

enter image description here

Итак, вы можете видеть, что я пытаюсь сделать.

Кто-нибудь может мне помочь?

Ответы

Ответ 1

Я нашел решение - я использовал маску свойства 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 с затухающей границей

Ответ 2

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

  • Создайте новый подкласс UIView, я назову его MaskingView
  • import QuartzCore framework!
  • Вставьте код ниже в init. (initWithCoder: и/или initWithFrame:)
  • Добавьте представление, в которое вы хотите применить опцию opacity в MaskingView. (В интерфейсе Builder, пользовательский редактор → Embed In → View. Затем выберите класс нового супервизора как MaskingView)
  • Отдайте должное iKiR, потому что я не знаю, как работает код, но он просто работает!

ПРИМЕЧАНИЯ:

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

Код:

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

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

Ответ 4

В этом учебнике есть Cocoanetics, который делает именно эту вещь.

Ответ 5

Здесь ответы 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;