UIView带有淡入淡出或模糊效果的边框

14

我正在寻找一种方法,可以向任意UIView添加逐渐淡化或模糊的边框(我不确定如何称呼此效果)。我不需要动画效果,我需要静态效果,例如我希望我的UITableView边框部分透明。这是我的示例:

enter image description here

所以你可以看到我正在尝试做什么。

有人能帮助我吗?

5个回答

16

我找到了一个解决方案 - 我使用了 CALayer 的属性 mask:

 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带有淡出边框效果


请问您能详细说明一下这是如何与UITableView结合使用的吗?谢谢! - jowie
7
我也想知道您是如何具体使用它的。能否请您发布一个更完整的代码块?maskLayer是什么?back layer是什么? - DoctorG
6
大家好,我来自2012年。我想了解详情。因此,我猜我会提供一个答案,分享一下我的看法。 - Mazyod

10

首先我想说,iKiR的答案已经足够了。我将代码原封不动地复制下来,在我的一点经验帮助下,我能够轻松地让它(在UITableView上)工作。

  1. 创建一个新的UIView子类,我将其称为MaskingView
  2. 导入QuartzCore框架!
  3. 将下面的代码粘贴到init中。(视情况使用initWithCoder:和/或initWithFrame:
  4. 将您要在MaskingView中应用透明度羽化的视图添加进去。(在Interface Builder中,使用Editor->Embed In->View。然后,选择新父视图的类为MaskingView
  5. 将所有信用归功于iKiR,因为我真的不知道这个代码是如何工作的,但它确实可以工作!

注意事项:

  • 我正在开发一款通用应用程序,下面的代码在两种设备上都可以正常工作!(iPhone/iPad)
  • 当使用Embed In -> UIView时,新视图会比子视图稍微大一些。你需要确保它恰好适合子视图。但是,在调整大小之前,请确保取消选中自动调整子视图。

代码:

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
你可以尝试在UITableView底部放置一个半透明的PNG文件。

3
好的,但在这种情况下,我将需要为不同的背景使用不同的PNG文件,我希望找到一个通用的解决方案。 - iKiR

3
Cocoanetics网站上有一个教程,可以做到这一点。

只有在使用静态颜色背景时才有效,对于图像背景无效,因为此教程会在你想要“淡出”的视图顶部添加彩色渐变。 - 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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接