为UIView添加渐变颜色和透明度

7
我知道如何创建和动画一个视图,就像iOS 6+带有新应用商店应用程序的共享子视图中的那个一样(请参见附加的屏幕截图),但我不知道如何在此视图上添加漂亮的透明着色效果。有人可以提供代码示例,使UIView看起来与屏幕截图中的完全相同吗?
附注:仅使用UIView的alpha属性无法实现这种效果。 enter image description here
7个回答

31

你可以将这个方法添加到一个UIView类别中,并在需要时重复使用。它会将从"theColor"到透明的线性黑色渐变应用到给定视图中。

为了使用CAGradientLayer对象,您的项目中应该有QuartzCore.framework库。

+ (void)addLinearGradientToView:(UIView *)theView withColor:(UIColor *)theColor transparentToOpaque:(BOOL)transparentToOpaque
{
    CAGradientLayer *gradient = [CAGradientLayer layer];

    //the gradient layer must be positioned at the origin of the view
    CGRect gradientFrame = theView.frame;
    gradientFrame.origin.x = 0;
    gradientFrame.origin.y = 0;
    gradient.frame = gradientFrame;

    //build the colors array for the gradient
    NSArray *colors = [NSArray arrayWithObjects:
                       (id)[theColor CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.9f] CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.6f] CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.4f] CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.3f] CGColor],
                       (id)[[theColor colorWithAlphaComponent:0.1f] CGColor],
                       (id)[[UIColor clearColor] CGColor],
                       nil];

    //reverse the color array if needed
    if(transparentToOpaque)
    {
       colors = [[colors reverseObjectEnumerator] allObjects];
    }

    //apply the colors and the gradient to the view
    gradient.colors = colors;

    [theView.layer insertSublayer:gradient atIndex:0];
}
请注意,您应将theView的backgroundColor设置为clearColor,以便它不会干扰渐变效果。 此外,对于屏幕截图中显示的结果,transparentToOpaque标志应设置为YES。

我按照您的要求做了,但代码没有效果,我在viewDidLoad中这样调用该方法:[UIView addLinearGradientToView:self.testView withColor:[UIColor redColor] transparentToOpaque:YES]; 当然,我没有出现任何问题地创建了该分类。我正在iOS 6模拟器上进行测试,并且QuartzCore框架也已添加并导入到此视图页面。 - JAHelia
1
我忘了将图层的原点设置为 (0,0)。我已经编辑了文章以反映这种更改。如果你想要一个“非线性”渐变,可以在颜色数组中尝试 alpha 组件的不同取值。 - PedroSilva
不错的提示:请注意,您应该将theView的backgroundColor设置为clearColor! - Mbt925

6

如果有人需要,这是 PedroSilva 的解决方案的 Swift 翻译(还添加了垂直选项)

class func addLinearGradientToView(view: UIView, colour: UIColor, transparntToOpaque: Bool, vertical: Bool)
{
    let gradient = CAGradientLayer()
    let gradientFrame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)
    gradient.frame = gradientFrame

    var colours = [
        colour.CGColor,
        colour.colorWithAlphaComponent(0.9).CGColor,
        colour.colorWithAlphaComponent(0.8).CGColor,
        colour.colorWithAlphaComponent(0.7).CGColor,
        colour.colorWithAlphaComponent(0.6).CGColor,
        colour.colorWithAlphaComponent(0.5).CGColor,
        colour.colorWithAlphaComponent(0.4).CGColor,
        colour.colorWithAlphaComponent(0.3).CGColor,
        colour.colorWithAlphaComponent(0.2).CGColor,
        colour.colorWithAlphaComponent(0.1).CGColor,
        UIColor.clearColor().CGColor
    ]

    if transparntToOpaque == true
    {
        colours = colours.reverse()
    }

    if vertical == true
    {
        gradient.startPoint = CGPointMake(0, 0.5)
        gradient.endPoint = CGPointMake(1, 0.5)
    }
    gradient.colors = colours
    view.layer.insertSublayer(gradient, atIndex: 0)
}

4
CAGradientLayer *layer = [CAGradientLayer layer];
layer.frame = yourView.bounds;
UIColor *blackColor = [UIColor colorWithWhite:0.42f alpha:1.0f];
UIColor *clearColor = [UIColor colorWithWhite:0.42f alpha:0.0f];
layer.colors = [NSArray arrayWithObjects:(id)clearColor.CGColor, (id)blackColor.CGColor, nil];
[myView.layer insertSublayer:layer atIndex:0];

其中layer是您视图的层级。


此示例导致崩溃:[CALayer setColors:]:向实例发送无法识别的选择器。 - JAHelia
你的视图对象属于哪个类? - Mikhail Viceman
我的视图只是UIView的一个子类。 - JAHelia
你更新后的代码在子视图上显示了这种颜色:http://dl.dropbox.com/u/57066689/mySubView.jpg 子视图上有一个带有文本“test”的按钮。我已经设置了一些透明度,但它仍然远远不及上面那个光泽视图。 - JAHelia
1
并且正如@Bird所建议的那样,使用myView.opaque = NO; - user207616
2
尝试玩一下颜色。例如,使用:UIColor *blackColor = [UIColor colorWithWhite:0.3f alpha:0.7f]; UIColor *clearColor = [UIColor colorWithWhite:0.0f alpha:0.7f]; - Mikhail Viceman

3

你可以使用半透明的png图片作为背景,来实现如下效果。确保将UIView的opaque属性设置为NO,就可以了。


2
好的答案并且简单易懂。此外,PNG 可以很小,例如 10x10(甚至 1x1),然后平铺,这样它就不会很重。 - Lee Harrison

3
没有什么魔法可以实现这个效果。你应该像苹果一样做。使用小的UIImageView并拉伸图片。
这个视图(包括图标的下半部分正方形)使用了可以拉伸的图片来产生这个效果。
你也应该采用这种方法。你的视图会非常轻,只需要在Photoshop中进行几次测试就可以获得正确的效果。
据我观察,苹果从不在iPhone上使用渐变层。这可能会更加消耗GPU,因为这样他们就可以节省很多图片...
这是一个类似的图片,可以用来测试。 enter image description here 希望对你有所帮助。

2

1

如果有人需要 Swift 3.X

func addLinearGradientToView(view: UIView, colour: UIColor, transparntToOpaque: Bool, vertical: Bool)
    {
        let gradient = CAGradientLayer()
        let gradientFrame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)
        gradient.frame = gradientFrame

        var colours = [
            colour.cgColor,
            colour.withAlphaComponent(0.9).cgColor,
            colour.withAlphaComponent(0.8).cgColor,
            colour.withAlphaComponent(0.7).cgColor,
            colour.withAlphaComponent(0.6).cgColor,
            colour.withAlphaComponent(0.5).cgColor,
            colour.withAlphaComponent(0.4).cgColor,
            colour.withAlphaComponent(0.3).cgColor,
            colour.withAlphaComponent(0.2).cgColor,
            colour.withAlphaComponent(0.1).cgColor,
            UIColor.clear.cgColor
        ]

        if transparntToOpaque == true
        {
            colours = colours.reversed()
        }

        if vertical == true
        {
            gradient.startPoint =  CGPoint(x: 0, y: 0.5)
            gradient.endPoint = CGPoint(x: 0, y: 0.5)
        }
        gradient.colors = colours
        view.layer.insertSublayer(gradient, at: 0)
    }

在Swift 3.x中的另一种方式

let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.blue.cgColor, UIColor.white.cgColor]
view.layer.insertSublayer(gradient, at: 0)

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