【问题标题】:UIView transparent gradientUIView 透明渐变
【发布时间】:2012-06-01 14:43:28
【问题描述】:

给定 iOS 上的任意 UIView,有没有办法使用 Core Graphics(想到 CAGradientLayer)对其应用“前景透明”渐变?

我不能使用标准的 CAGradientLayer,因为背景比 UIColor 更复杂。我也不能覆盖 PNG,因为当我的子视图沿其父垂直滚动视图滚动时,背景会发生变化(见图)。

我有一个不优雅的后备:让我的 uiview 剪辑它的子视图,并在滚动父滚动视图时移动背景的预渲染渐变 png。

【问题讨论】:

  • 背景是什么?当滚动视图滚动时,它是如何“改变”的?
  • 正如@jab 在下面的回答中提到的那样,一般认为这个问题可能更有用,因为将渐变蒙版应用于任何视图,而不是将渐变蒙版应用于 scroll i> 视图(就像 OP 请求一样)。创建这样的容器视图(使用下面描述的方法之一),然后将滚动视图添加为子视图,可以创建所需的效果。看起来人们试图将渐变应用到滚动视图本身并没有得到他们想要的东西时有些困惑。

标签: iphone ios core-graphics cagradientlayer


【解决方案1】:

这是一个非常简单的解决方法:应用 CAGradientLayer 作为我的子视图的蒙版。

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = _fileTypeScrollView.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor, (id)[UIColor clearColor].CGColor, nil];
gradientLayer.startPoint = CGPointMake(0.8f, 1.0f);
gradientLayer.endPoint = CGPointMake(1.0f, 1.0f);
_fileTypeScrollView.layer.mask = gradientLayer;

感谢Cocoanetics 为我指明了正确的方向!

【讨论】:

  • 我使用这段代码将渐变添加到一个非常相似的水平 UIScrollView。看起来一切都很好,但是当你真正滚动时——从右边进来的视图是透明的。就好像渐变应用于滚动视图上的实际视图,而不是它们上方的图层。我做错了什么?
  • 如何使用此代码创建垂直渐变?
  • 未来读者:这是另一个有用的线程 - stackoverflow.com/questions/23074539/…
  • stackoverflow.com/a/53307483/592454 中所述,渐变层可能应该应用于滚动视图父视图,而不是滚动视图本身。
【解决方案2】:

这就是我要做的。

第 1 步定义自定义渐变视图 (Swift 4):

import UIKit

class GradientView: UIView {
    override open class var layerClass: AnyClass {
        return CAGradientLayer.classForCoder()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let gradientLayer = self.layer as! CAGradientLayer
        gradientLayer.colors = [
            UIColor.white.cgColor,
            UIColor.init(white: 1, alpha: 0).cgColor
        ]
        backgroundColor = UIColor.clear
    }
}

第 2 步 - 将 UIView 拖放到情节提要中,并将其自定义类设置为 GradientView

例如,上面的渐变视图是这样的:


https://github.com/yzhong52/GradientViewDemo

【讨论】:

  • @Elsammak 我认为这是因为您没有将 UIview 的背景颜色设置为清除。有关详细信息,请参阅 Smaily Carrilho 的编辑。
  • 另外提及mapView.addSubview(mapGradientView)
  • @SatnamSync 感谢您的编辑。但是第 2 步相当于mapView.addSubview(mapGradientView)。本质上,如果我们在故事板中有视图,我们不应该再次调用它。但如果你想用代码做事,那将是正确的做法。
  • @YuchenZhong 我刚刚尝试了这个,以编程方式和情节提要两种方式都需要。我不知道谷歌地图是否需要它,但是 UIView(Class - MKMapView, 这就是我使用它的方式) 它确实需要提及。
  • @SatnamSync 您的代码中可能存在错误。我放了tgt一个demo,看看有没有帮助。 github.com/yzhong52/GradientViewDemo
【解决方案3】:

我刚遇到同样的问题,最后写了自己的课程。这似乎是严重的矫枉过正,但这是我能找到的唯一方法来做透明渐变。你可以看到我的writeup and code example here

它基本上归结为创建两个图像的自定义 UIView。一种是纯色,另一种是用作图像蒙版的渐变色。从那里我将生成的图像应用到 uiview.layer.content。

希望对你有帮助 乔

【讨论】:

    【解决方案4】:

    我使用了上面接受的(OP's)答案并遇到了an upvoted comment 中提到的相同问题 - 当视图滚动时,屏幕外开始的所有内容现在都是透明的,被蒙版覆盖。

    解决方案是将渐变层添加为 superview 的蒙版,而不是 滚动视图 的蒙版。在我的例子中,我使用的是一个文本视图,它包含在一个名为 contentView 的视图中。

    我添加了第三种颜色并使用locations 代替了startPointendPoint,因此文本视图下方的项目仍然可见。

    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = self.contentView!.bounds
    gradientLayer.colors = [UIColor.white.cgColor, UIColor.clear.cgColor, UIColor.white.cgColor]
    
    // choose position for gradient, aligned to bottom of text view
    let bottomOffset = (self.textView!.frame.size.height + self.textView!.frame.origin.y + 5)/self.contentView!.bounds.size.height
    let topOffset = bottomOffset - 0.1
    let bottomCoordinate = NSNumber(value: Double(bottomOffset))
    let topCoordinate = NSNumber(value: Double(topOffset))
    gradientLayer.locations = [topCoordinate, bottomCoordinate, bottomCoordinate]
    
    self.contentView!.layer.mask = gradientLayer
    

    以前,在屏幕外开始的文字是永久不可见的。通过我的修改,滚动按预期工作,并且“关闭”按钮没有被遮罩覆盖。

    【讨论】:

      【解决方案5】:

      我不想这么说,但我认为您进入了自定义 UIView 领域。我想我会尝试在覆盖 drawRect 例程的自定义 UIView 中实现这一点。

      有了这个,您可以拥有该视图,放置在您的实际滚动视图之上,并让您的渐变视图(如果您愿意)“传递”所有触摸事件(即放弃第一响应者)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-18
        • 1970-01-01
        • 1970-01-01
        • 2013-03-13
        • 2013-04-28
        • 1970-01-01
        相关资源
        最近更新 更多