2

我希望将渐变背景添加到 ASDisplayNode/ASButtonNode。我尝试创建一个渐变层并将其添加为像这样的子层 -

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = button.frame;
gradient.colors = @[[UIColor redColor], [UIColor blueColor]];
[button.view.layer insertSublayer:gradient atIndex:0];

wherebutton是 type ASButtonNode,但这只是给按钮一个白色背景。我也找不到很多文档来实现这一点。

如何在给定数组UIColorCGFloat角度的情况下添加背景?

谢谢

4

4 回答 4

3

斯威夫特 3。

extension UIView {

       func gradient(color1: UIColor, color2: UIColor) -> CAGradientLayer {
             let gradient: CAGradientLayer = CAGradientLayer()
             gradient.colors = [color1.cgColor, color2.cgColor]
             gradient.locations = [0.0 , 1.0]
             gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
             gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
             gradient.frame = CGRect(x: 0.0, y: 0.0, width: frame.size.width, height: frame.size.height)
             return gradient
          } 
    }

例子:

let gradient = self.cardGradientNode.view.gradient(
    color1: gradient.start, 
    color2: gradient.end
)
self.cardGradientNode.view.layer.insertSublayer(gradient, at: 0)

结果: 在此处输入图像描述

于 2017-08-11T14:57:03.410 回答
1

这是我完全基于 Texture/AsyncDisplayKit 的实现。这允许一个完全通用的 Gradient Node 类,它不固定整个类的任何值,迄今为止其他解决方案强制执行,因为 drawRect 是类函数,而不是实例函数。

class GradientNode: ASDisplayNode {

    private let startUnitPoint: CGPoint
    private let endUnitPoint: CGPoint
    private let colors: [UIColor]
    private let locations: [CGFloat]?

    override class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled isCancelledBlock: () -> Bool, isRasterizing: Bool) {

        guard let parameters = parameters as? GradientNode else {
            CCLog.assert("Expected type SimpleGradientNode to be returned")
            return
        }

        // Calculate the start and end points
        let startUnitX = parameters.startUnitPoint.x
        let startUnitY = parameters.startUnitPoint.y
        let endUnitX = parameters.endUnitPoint.x
        let endUnitY = parameters.endUnitPoint.y

        let startPoint = CGPoint(x: bounds.width * startUnitX + bounds.minX, y: bounds.height * startUnitY + bounds.minY)
        let endPoint = CGPoint(x: bounds.width * endUnitX + bounds.minX, y: bounds.height * endUnitY + bounds.minY)

        let context = UIGraphicsGetCurrentContext()!
        context.saveGState()
        context.clip(to: bounds)

        guard let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(),
                                        colors: parameters.colors.map { $0.cgColor } as CFArray,
                                        locations: parameters.locations) else {
            CCLog.assert("Unable to create CGGradient")
            return
        }

        context.drawLinearGradient(gradient,
                                   start: startPoint,
                                   end: endPoint,
                                   options: CGGradientDrawingOptions.drawsAfterEndLocation)
        context.restoreGState()
    }

    init(startingAt startUnitPoint: CGPoint, endingAt endUnitPoint: CGPoint, with colors: [UIColor], for locations: [CGFloat]? = nil) {
        self.startUnitPoint = startUnitPoint
        self.endUnitPoint = endUnitPoint
        self.colors = colors
        self.locations = locations

        super.init()
    }

    override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
        return self
    }

只需创建一个 GradientNote 并在 init() 函数中填写参数即可。然后把它当作一个普通的Node,让ASDK做剩下的工作!

coverTitleBackgroundNode = GradientNode(startingAt: CGPoint(x: 0.5, y: 1.0),
                                        endingAt: CGPoint(x: 0.5, y: 0.0),
                                        with: [UIColor.black.withAlphaComponent(Constants.CoverTitleBackgroundBlackAlpha), UIColor.clear])
coverTitleBackgroundNode!.isLayerBacked = true
coverTitleBackgroundNode!.isOpaque = false
automaticallyManagesSubnodes = true
于 2017-11-04T18:41:42.107 回答
0

您在 AsyncDisplayKit 的 GitHub 问题上提出了同样的问题: https ://github.com/facebookarchive/AsyncDisplayKit/issues/3253

你得到了两种可能性的回答:

1:创建一个 CAGradientLayer 并将其添加为节点的子层

2:覆盖节点的 + (void)draw... 方法并在那里绘制渐变。

第一个选项必须在主线程中,这样就不会赋予我们 ASDK 的强大功能。第二个选项更复杂,但我可以从 ASDK 示例项目中发布一些示例。

基于 https://github.com/facebookarchive/AsyncDisplayKit/blob/master/examples/VerticalWithinHorizo​​ntalScrolling/Sample/RandomCoreGraphicsNode.m

https://www.raywenderlich.com/124311/asyncdisplaykit-2-0-tutorial-getting-started

1. 子类 ASDisplayNode

#import <AsyncDisplayKit/AsyncDisplayKit.h>

@interface GradientNode : ASDisplayNode

@end

2.覆盖drawRect方法(2种颜色的基本渐变-黑色到透明)

@implementation GradientNode

+(void)drawRect:(CGRect)bounds withParameters:(id)parameters isCancelled:
    (asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:
    (BOOL)isRasterizing{

        CGFloat locations[2];
        NSMutableArray *colors = [NSMutableArray arrayWithCapacity:2];
        [colors addObject:(id)[[UIColor clearColor] CGColor]];
        locations[0] = 0.0;
        [colors addObject:(id)[[UIColor blackColor] CGColor]];
        locations[1] = 1.0;

        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, 
        (CFArrayRef)colors, locations);

        CGContextDrawLinearGradient(ctx, gradient, CGPointZero, 
        CGPointMake(bounds.size.width, bounds.size.height), 0);

        CGGradientRelease(gradient);
        CGColorSpaceRelease(colorSpace);
    }

    @end

3.设置节点(重要!当使用具有清晰颜色的渐变时,否则它会绘制一个不透明的黑色视图)

_gradientNode = [GradientNode new];
_gradientNode.layerBacked = YES;
_gradientNode.opaque = NO;
于 2017-07-19T10:30:11.913 回答
0
extension ASDisplayNode {
    func gradient(from color1: UIColor, to color2: UIColor) {
        DispatchQueue.main.async {

            let size = self.view.frame.size
            let width = size.width
            let height = size.height


            let gradient: CAGradientLayer = CAGradientLayer()
            gradient.colors = [color1.cgColor, color2.cgColor]
            gradient.locations = [0.0 , 1.0]
            gradient.startPoint = CGPoint(x: 0.0, y: height/2)
            gradient.endPoint = CGPoint(x: 1.0, y: height/2)
            gradient.cornerRadius = 30
            gradient.frame = CGRect(x: 0.0, y: 0.0, width: width, height: height)
            self.view.layer.insertSublayer(gradient, at: 0)
        }
    }
}

例子:

node.gradient(from: .white, to: .red)
于 2018-01-15T15:02:30.597 回答