swifttuplesvariadic-functionsobjective-c-swift-bridgensgradient

How can I create a NSGradient from an array of colors and floats?


I have an array of NSColors, and an array of CGFloats signifying gradient stops. I can't figure out how to use these arrays to initialize a NSGradient.

I tried making these into an array of (NSColor, CGFloat)s, but NSGradient(colorsAndLocations: won't take it, since it expects varargs:

The code <code>let gradient = NSGradient(colorsAndLocations: colorsAndLocations)</code> yielding the error <code>Cannot convert value of type '[(NSColor, CGFloat)]' to expected argument type '(NSColor, CGFloat)'</code>

And NSGradient(colors:, atLocations:, colorSpace:) expects a UnsafePointer which I have no idea how to properly handle in Swift, if there is even such a way.


Solution

  • I assume you know this usage:

    let cAndL: [(NSColor, CGFloat)] = [(NSColor.redColor(), 0.0), (NSColor.greenColor(), 1.0)]
    let gradient = NSGradient(colorsAndLocations: cAndL[0], cAndL[1])
    

    Unfortunately, Swift does not provide us a way to give Arrays to variadic functions.


    And the second portion. If some API claims UnsafePointer<T> as an array, you can create a Swift Array of T, and pass it directly to the API.

    let colors = [NSColor.redColor(), NSColor.greenColor()]
    let locations: [CGFloat] = [0.0, 1.0]
    let gradient2 = NSGradient(colors: colors, atLocations: locations, colorSpace: NSColorSpace.genericRGBColorSpace())
    

    If you want to utilize an Array of (NSColor, CGFloat), you can write something like this:

    let gradient3 = NSGradient(colors: cAndL.map{$0.0}, atLocations: cAndL.map{$0.1}, colorSpace: NSColorSpace.genericRGBColorSpace())