2017-04-10 69 views
1

我正在尋找添加漸變背景到ASDisplayNode/ASButtonNode。 我試圖創建一個梯度層和將其添加爲這樣的子層 -如何添加漸變到ASDisplayNode或ASButtonNode

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

button哪裏是ASButtonNode類型的,但是這只是給出了一個白色背景到按鈕。我還沒有找到很多文件來實現這一目標。

如何添加一個背景給定一個UIColorCGFloat角度的數組?

感謝

+0

一般編輯節點的觀點應該是在主線程,如果沒有它拋出一個異常 - 「這個方法必須被稱爲主線程」。我試圖找到一個很酷的例子,說明如何以相對簡單的方式實現它。 –

回答

2

夫特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) 

結果: enter image description here

0

你問上AsyncDisplayKit的GitHub的問題,同樣的問題: https://github.com/facebookarchive/AsyncDisplayKit/issues/3253

你已經回答了2種可能:

1:創建一個CAGradientLayer並將其添加作爲節點的子層

2:覆蓋節點的+(void)draw ...方法並在那裏繪製漸變。

第一個選項必須在主線程中,所以不會授予我們ASDK的威力。 第二個選項更復雜,但我可以從ASDK示例項目中發佈一些示例。

基於https://github.com/facebookarchive/AsyncDisplayKit/blob/master/examples/VerticalWithinHorizontalScrolling/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. Setuping節點(重要!使用具有清晰的顏色漸變時,否則繪製一個opaqued黑色視圖)

_gradientNode = [GradientNode new]; 
_gradientNode.layerBacked = YES; 
_gradientNode.opaque = NO; 
0

這是我的完全紋理/ AsyncDisplayKi基於t的實現。這允許一個完全通用的漸變節點類,它不修復整個類的任何值,其他解決方案到目前爲止都是強制的,因爲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()函數中的參數。然後將它視爲一個常規節點,讓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 
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)