如何在 swift 中存储 NSGradient(colorsAndLocations:) 的元组
How store a tuple for NSGradient(colorsAndLocations:) in swift
要将渐变应用于 NSView,似乎最好制作一个 class 从 NSView 继承并覆盖设置路径和绘制渐变的 draw 方法。
class GradientView: NSView {
var startColor = NSColor.red
var startPosition: CGFloat = 0
var endColor = NSColor.white
var endPosition: CGFloat = 1
var rotation: CGFloat = 0
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let bgGradient = NSGradient(colorsAndLocations: (startColor, startPosition), (endColor, endPosition))
let path = NSBezierPath.init(rect: self.bounds)
bgGradient?.draw(in: path, angle: rotation)
}
}
(让我知道是否有 better/easier 方法...)
效果很好,但现在我想发送一组自定义的颜色和色标。注意:*使用上述方法,我仅限于定义两个(startColor & startPosition 和 endColor & endPosition)。
我想使用(一个数组?)元组(包含多种颜色及其停止值)。设置颜色和位置的 API 是 NSGradient(colorsAndLocations:)
并使用元组 (NSColor, CGFloat)
.
我可以添加一个像 var colorStopArray: [(color: NSColor, stop: CGFloat)] = []
这样的参数来创建一个(这样的)元组数组。我也可以附加值:colorStopArray.append((startColor, startPosition)).
但是我怎样才能将它分配给 API?
我尝试了很多方法,但它们都会导致错误(例如,尝试 NSGradient(colorsAndLocations: colorStopArray.flatMap{return ([=15=].color, [=15=].stop)})
)
那么如何将许多自定义颜色+位置发送到上面的 class(或者希望是更好的建议)来创建自定义渐变(然后将在我的 NSView 上绘制)?
With this above method, I am limited to defining two (the startColor & startPosition and endColor & endPosition) only.
不,你不是。这是一个可变参数;您可以根据需要添加任意数量的元组。这很好用:
let startColor = NSColor.red
let startPosition: CGFloat = 0
let middleColor = NSColor.blue
let middlePosition: CGFloat = 0.5
var endColor = NSColor.white
var endPosition: CGFloat = 1
let bgGradient = NSGradient(colorsAndLocations:
(startColor, startPosition),
(middleColor, middlePosition),
(endColor, endPosition))
如果问题是“我可以将数组转换为可变参数吗?”,那么很遗憾,答案是否定的。 Swift 语言缺少此功能(“splatting”)。在 Swift 中调用可变参数的唯一方法是作为可变参数。
可让您提供一组颜色和停止位置的初始化程序是 init(colors:atLocations:colorSpace:)
。因此,如果这是您想要提供的,请改为调用该初始化程序。
利用马特的线索,我替换了 let 行(使用更合适的 API init(colors:atLocations:colorSpace:)
):
let bgGradient = NSGradient(colorsAndLocations: (startColor, startPosition), (endColor, endPosition))
与
let bgGradient = NSGradient(colors: colorStopArray.map { [=11=].color }, atLocations: colorStopArray.map { [=11=].stop }, colorSpace: NSColorSpace.genericRGB)
现在它的功能如我所愿。
要将渐变应用于 NSView,似乎最好制作一个 class 从 NSView 继承并覆盖设置路径和绘制渐变的 draw 方法。
class GradientView: NSView {
var startColor = NSColor.red
var startPosition: CGFloat = 0
var endColor = NSColor.white
var endPosition: CGFloat = 1
var rotation: CGFloat = 0
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let bgGradient = NSGradient(colorsAndLocations: (startColor, startPosition), (endColor, endPosition))
let path = NSBezierPath.init(rect: self.bounds)
bgGradient?.draw(in: path, angle: rotation)
}
}
(让我知道是否有 better/easier 方法...)
效果很好,但现在我想发送一组自定义的颜色和色标。注意:*使用上述方法,我仅限于定义两个(startColor & startPosition 和 endColor & endPosition)。
我想使用(一个数组?)元组(包含多种颜色及其停止值)。设置颜色和位置的 API 是 NSGradient(colorsAndLocations:)
并使用元组 (NSColor, CGFloat)
.
我可以添加一个像 var colorStopArray: [(color: NSColor, stop: CGFloat)] = []
这样的参数来创建一个(这样的)元组数组。我也可以附加值:colorStopArray.append((startColor, startPosition)).
但是我怎样才能将它分配给 API?
我尝试了很多方法,但它们都会导致错误(例如,尝试 NSGradient(colorsAndLocations: colorStopArray.flatMap{return ([=15=].color, [=15=].stop)})
)
那么如何将许多自定义颜色+位置发送到上面的 class(或者希望是更好的建议)来创建自定义渐变(然后将在我的 NSView 上绘制)?
With this above method, I am limited to defining two (the startColor & startPosition and endColor & endPosition) only.
不,你不是。这是一个可变参数;您可以根据需要添加任意数量的元组。这很好用:
let startColor = NSColor.red
let startPosition: CGFloat = 0
let middleColor = NSColor.blue
let middlePosition: CGFloat = 0.5
var endColor = NSColor.white
var endPosition: CGFloat = 1
let bgGradient = NSGradient(colorsAndLocations:
(startColor, startPosition),
(middleColor, middlePosition),
(endColor, endPosition))
如果问题是“我可以将数组转换为可变参数吗?”,那么很遗憾,答案是否定的。 Swift 语言缺少此功能(“splatting”)。在 Swift 中调用可变参数的唯一方法是作为可变参数。
可让您提供一组颜色和停止位置的初始化程序是 init(colors:atLocations:colorSpace:)
。因此,如果这是您想要提供的,请改为调用该初始化程序。
利用马特的线索,我替换了 let 行(使用更合适的 API init(colors:atLocations:colorSpace:)
):
let bgGradient = NSGradient(colorsAndLocations: (startColor, startPosition), (endColor, endPosition))
与
let bgGradient = NSGradient(colors: colorStopArray.map { [=11=].color }, atLocations: colorStopArray.map { [=11=].stop }, colorSpace: NSColorSpace.genericRGB)
现在它的功能如我所愿。