有没有一种简单的方法可以在 Swift 中实现颜色选择器弹出框?我可以利用任何内置 UI 元素来实现此目的吗?
这是我制作的一个,非常简单。它只是一个轻量级 UIView,允许您指定元素大小,以防您想要阻塞区域 (elementSize > 1)。它在界面生成器中绘制自身,以便您可以设置元素大小并查看结果。只需将界面生成器中的视图之一设置为此类,然后将自己设置为委托即可。当有人点击或拖动它以及该位置的 uicolor 时,它会告诉您。它会将自己绘制到自己的边界,除了这个类之外不需要任何其他东西,不需要图像。
internal protocol HSBColorPickerDelegate : NSObjectProtocol {
func HSBColorColorPickerTouched(sender:HSBColorPicker, color:UIColor, point:CGPoint, state:UIGestureRecognizerState)
}
@IBDesignable
class HSBColorPicker : UIView {
weak internal var delegate: HSBColorPickerDelegate?
let saturationExponentTop:Float = 2.0
let saturationExponentBottom:Float = 1.3
@IBInspectable var elementSize: CGFloat = 1.0 {
didSet {
setNeedsDisplay()
}
}
private func initialize() {
self.clipsToBounds = true
let touchGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.touchedColor(gestureRecognizer:)))
touchGesture.minimumPressDuration = 0
touchGesture.allowableMovement = CGFloat.greatestFiniteMagnitude
self.addGestureRecognizer(touchGesture)
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
for y : CGFloat in stride(from: 0.0 ,to: rect.height, by: elementSize) {
var saturation = y < rect.height / 2.0 ? CGFloat(2 * y) / rect.height : 2.0 * CGFloat(rect.height - y) / rect.height
saturation = CGFloat(powf(Float(saturation), y < rect.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = y < rect.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(rect.height - y) / rect.height
for x : CGFloat in stride(from: 0.0 ,to: rect.width, by: elementSize) {
let hue = x / rect.width
let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
context!.setFillColor(color.cgColor)
context!.fill(CGRect(x:x, y:y, width:elementSize,height:elementSize))
}
}
}
func getColorAtPoint(point:CGPoint) -> UIColor {
let roundedPoint = CGPoint(x:elementSize * CGFloat(Int(point.x / elementSize)),
y:elementSize * CGFloat(Int(point.y / elementSize)))
var saturation = roundedPoint.y < self.bounds.height / 2.0 ? CGFloat(2 * roundedPoint.y) / self.bounds.height
: 2.0 * CGFloat(self.bounds.height - roundedPoint.y) / self.bounds.height
saturation = CGFloat(powf(Float(saturation), roundedPoint.y < self.bounds.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = roundedPoint.y < self.bounds.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(self.bounds.height - roundedPoint.y) / self.bounds.height
let hue = roundedPoint.x / self.bounds.width
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
}
func getPointForColor(color:UIColor) -> CGPoint {
var hue: CGFloat = 0.0
var saturation: CGFloat = 0.0
var brightness: CGFloat = 0.0
color.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: nil);
var yPos:CGFloat = 0
let halfHeight = (self.bounds.height / 2)
if (brightness >= 0.99) {
let percentageY = powf(Float(saturation), 1.0 / saturationExponentTop)
yPos = CGFloat(percentageY) * halfHeight
} else {
//use brightness to get Y
yPos = halfHeight + halfHeight * (1.0 - brightness)
}
let xPos = hue * self.bounds.width
return CGPoint(x: xPos, y: yPos)
}
@objc func touchedColor(gestureRecognizer: UILongPressGestureRecognizer) {
if (gestureRecognizer.state == UIGestureRecognizerState.began) {
let point = gestureRecognizer.location(in: self)
let color = getColorAtPoint(point: point)
self.delegate?.HSBColorColorPickerTouched(sender: self, color: color, point: point, state:gestureRecognizer.state)
}
}
}
基于 Joel Teply 代码 (Swift 4),顶部有灰色条:
import UIKit
class ColorPickerView : UIView {
var onColorDidChange: ((_ color: UIColor) -> ())?
let saturationExponentTop:Float = 2.0
let saturationExponentBottom:Float = 1.3
let grayPaletteHeightFactor: CGFloat = 0.1
var rect_grayPalette = CGRect.zero
var rect_mainPalette = CGRect.zero
// adjustable
var elementSize: CGFloat = 1.0 {
didSet {
setNeedsDisplay()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
self.clipsToBounds = true
let touchGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.touchedColor(gestureRecognizer:)))
touchGesture.minimumPressDuration = 0
touchGesture.allowableMovement = CGFloat.greatestFiniteMagnitude
self.addGestureRecognizer(touchGesture)
}
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
rect_grayPalette = CGRect(x: 0, y: 0, width: rect.width, height: rect.height * grayPaletteHeightFactor)
rect_mainPalette = CGRect(x: 0, y: rect_grayPalette.maxY,
width: rect.width, height: rect.height - rect_grayPalette.height)
// gray palette
for y in stride(from: CGFloat(0), to: rect_grayPalette.height, by: elementSize) {
for x in stride(from: (0 as CGFloat), to: rect_grayPalette.width, by: elementSize) {
let hue = x / rect_grayPalette.width
let color = UIColor(white: hue, alpha: 1.0)
context!.setFillColor(color.cgColor)
context!.fill(CGRect(x:x, y:y, width:elementSize, height:elementSize))
}
}
// main palette
for y in stride(from: CGFloat(0), to: rect_mainPalette.height, by: elementSize) {
var saturation = y < rect_mainPalette.height / 2.0 ? CGFloat(2 * y) / rect_mainPalette.height : 2.0 * CGFloat(rect_mainPalette.height - y) / rect_mainPalette.height
saturation = CGFloat(powf(Float(saturation), y < rect_mainPalette.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = y < rect_mainPalette.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(rect_mainPalette.height - y) / rect_mainPalette.height
for x in stride(from: (0 as CGFloat), to: rect_mainPalette.width, by: elementSize) {
let hue = x / rect_mainPalette.width
let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
context!.setFillColor(color.cgColor)
context!.fill(CGRect(x:x, y: y + rect_mainPalette.origin.y,
width: elementSize, height: elementSize))
}
}
}
func getColorAtPoint(point: CGPoint) -> UIColor
{
var roundedPoint = CGPoint(x:elementSize * CGFloat(Int(point.x / elementSize)),
y:elementSize * CGFloat(Int(point.y / elementSize)))
let hue = roundedPoint.x / self.bounds.width
// main palette
if rect_mainPalette.contains(point)
{
// offset point, because rect_mainPalette.origin.y is not 0
roundedPoint.y -= rect_mainPalette.origin.y
var saturation = roundedPoint.y < rect_mainPalette.height / 2.0 ? CGFloat(2 * roundedPoint.y) / rect_mainPalette.height
: 2.0 * CGFloat(rect_mainPalette.height - roundedPoint.y) / rect_mainPalette.height
saturation = CGFloat(powf(Float(saturation), roundedPoint.y < rect_mainPalette.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = roundedPoint.y < rect_mainPalette.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(rect_mainPalette.height - roundedPoint.y) / rect_mainPalette.height
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
}
// gray palette
else{
return UIColor(white: hue, alpha: 1.0)
}
}
@objc func touchedColor(gestureRecognizer: UILongPressGestureRecognizer){
let point = gestureRecognizer.location(in: self)
let color = getColorAtPoint(point: point)
self.onColorDidChange?(color)
}
}
用途:
let colorPickerView = ColorPickerView()
colorPickerView.onColorDidChange = { [weak self] color in
DispatchQueue.main.async {
// use picked color for your needs here...
self?.view.backgroundColor = color
}
}
// add it to some view and set constraints
...
Swift 3.0 版本的 @joel-teply 的回答:
internal protocol HSBColorPickerDelegate : NSObjectProtocol {
func HSBColorColorPickerTouched(sender:HSBColorPicker, color:UIColor, point:CGPoint, state:UIGestureRecognizerState)
}
@IBDesignable
class HSBColorPicker : UIView {
weak internal var delegate: HSBColorPickerDelegate?
let saturationExponentTop:Float = 2.0
let saturationExponentBottom:Float = 1.3
@IBInspectable var elementSize: CGFloat = 1.0 {
didSet {
setNeedsDisplay()
}
}
private func initialize() {
self.clipsToBounds = true
let touchGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.touchedColor(gestureRecognizer:)))
touchGesture.minimumPressDuration = 0
touchGesture.allowableMovement = CGFloat.greatestFiniteMagnitude
self.addGestureRecognizer(touchGesture)
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
for y in stride(from: (0 as CGFloat), to: rect.height, by: elementSize) {
var saturation = y < rect.height / 2.0 ? CGFloat(2 * y) / rect.height : 2.0 * CGFloat(rect.height - y) / rect.height
saturation = CGFloat(powf(Float(saturation), y < rect.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = y < rect.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(rect.height - y) / rect.height
for x in stride(from: (0 as CGFloat), to: rect.width, by: elementSize) {
let hue = x / rect.width
let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
context!.setFillColor(color.cgColor)
context!.fill(CGRect(x:x, y:y, width:elementSize,height:elementSize))
}
}
}
func getColorAtPoint(point:CGPoint) -> UIColor {
let roundedPoint = CGPoint(x:elementSize * CGFloat(Int(point.x / elementSize)),
y:elementSize * CGFloat(Int(point.y / elementSize)))
var saturation = roundedPoint.y < self.bounds.height / 2.0 ? CGFloat(2 * roundedPoint.y) / self.bounds.height
: 2.0 * CGFloat(self.bounds.height - roundedPoint.y) / self.bounds.height
saturation = CGFloat(powf(Float(saturation), roundedPoint.y < self.bounds.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = roundedPoint.y < self.bounds.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(self.bounds.height - roundedPoint.y) / self.bounds.height
let hue = roundedPoint.x / self.bounds.width
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
}
func getPointForColor(color:UIColor) -> CGPoint {
var hue:CGFloat=0;
var saturation:CGFloat=0;
var brightness:CGFloat=0;
color.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: nil);
var yPos:CGFloat = 0
let halfHeight = (self.bounds.height / 2)
if (brightness >= 0.99) {
let percentageY = powf(Float(saturation), 1.0 / saturationExponentTop)
yPos = CGFloat(percentageY) * halfHeight
} else {
//use brightness to get Y
yPos = halfHeight + halfHeight * (1.0 - brightness)
}
let xPos = hue * self.bounds.width
return CGPoint(x: xPos, y: yPos)
}
func touchedColor(gestureRecognizer: UILongPressGestureRecognizer){
let point = gestureRecognizer.location(in: self)
let color = getColorAtPoint(point: point)
self.delegate?.HSBColorColorPickerTouched(sender: self, color: color, point: point, state:gestureRecognizer.state)
}
}
在 iOS 14 中,Apple 现在实现了标准的 UIColorPickerViewController 和关联的 UIColorWell,它是一个颜色样本,可自动调出 UIColorPicker 来选择颜色。
您可以通过使用 Xcode 12 或更高版本创建一个针对 iOS 14+ 的 Swift App 项目来测试 ColorPicker,然后尝试以下简单的代码:
import SwiftUI
struct ContentView: View {
@State private var bgColor = Color.white
var body: some View {
VStack {
ColorPicker("Set the background color",
selection: $bgColor,
supportsOpacity: true)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(bgColor)
}
}
将
supportsOpacity
更改为 false
以摆脱不透明度滑块并仅允许完全不透明的颜色。
ColorPicker 显示两种不同的选择模式:
没有 alpha 的颜色选择器:
感谢您的出发点。
我从那里获取它并编写了一个完整的 Color PickerViewController ,其中包含自定义 UIView 和一些绘图代码。
我制作了自定义 UIView @IBDesignable,以便可以在 InterfaceBuilder 中呈现它。
我快速添加了代码,使用 iOS 14 中发布的 Apple 颜色选择器为 ViewController 实现颜色选择器。确保您的部署信息至少为 IOS 14.0 或更高版本。请参阅 https://developer.apple.com/documentation/uikit/uicolorpickerviewcontroller 以供参考。
将颜色选择器委托添加到类中,并声明一个颜色选择器对象:
class ViewController: UIViewController, UIColorPickerViewControllerDelegate {
let colorPicker = UIColorPickerViewController()
在 viewDidLoad 的最后,我将 colorPicker 委托设置为 self
colorPicker.delegate = self
} // ends viewDidLoad
我使用单一颜色选择器为几个不同的对象选择颜色。当我向用户呈现颜色选择器时,我将布尔标志设置为 true 以指示显示颜色选择器的原因。
resetAllColorChangeFlags() // First make sure all the booleans are false for robust design
changingScreenBackgroundColor = true
present(colorPicker, animated: true, completion: nil)
我添加了 API 来处理 colorPickerViewControllerDidSelectColor 和 colorPickerViewControllerDidFinish
colorPickerViewControllerDidSelectColor 检查布尔标志,并为适当的对象设置颜色属性。如果颜色应用于图层中的边框颜色,则使用 cgColor。
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
if changingScreenBackgroundColor
{
self.view.backgroundColor = viewController.selectedColor
}
if addingATintCircle
{
pointerToThisTintView.backgroundColor = viewController.selectedColor
}
if changingTextBackgroundColor
{
pointerToTextObjectSelected.backgroundColor = viewController.selectedColor
}
if changingTextColor
{
pointerToTextObjectSelected.textColor = viewController.selectedColor
}
if changingTextBorderColor
{
pointerToTextObjectSelected.layer.borderColor = viewController.selectedColor.cgColor
}
if changingPhotoBorderColor
{
pointerToPhotoObjectSelected.layer.borderColor = viewController.selectedColor.cgColor
}
if changingCameraBorderColor {
cameraView.layer.borderColor = viewController.selectedColor.cgColor
}
} // ends colorPickerViewControllerDidSelectColor
colorPickerViewControllerDidFinish 仅用于重置所有布尔标志,这些标志指示为什么向用户呈现颜色选择器。
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController)
{
resetAllColorChangeFlags()
} // ends colorPickerViewControllerDidFinish
这是我的重置例程:
func resetAllColorChangeFlags()
{
changingFunTextColor = false
changingFunTextFirstColorForGradient = false
changingFunTextSecondColorForGradient = false
changingScreenBackgroundColor = false
changingTextBackgroundColor = false
changingTextColor = false
changingTextBorderColor = false
changingPhotoBorderColor = false
changingCameraBorderColor = false
addingATintToAPhotoObject = false
addingATintCircle = false
addingAColorForGradients = false
} // ends resetAllColorChangeFlags
根据Christian1313的回答,我添加了较深的颜色:
@IBDesignable final public class SwiftColorView: UIView {
weak var colorSelectedDelegate: ColorDelegate?
@IBInspectable public var numColorsX:Int = 10 {
didSet {
setNeedsDisplay()
}
}
@IBInspectable public var numColorsY:Int = 18 {
didSet {
setNeedsDisplay()
}
}
@IBInspectable public var coloredBorderWidth:Int = 10 {
didSet {
setNeedsDisplay()
}
}
@IBInspectable public var showGridLines:Bool = false {
didSet {
setNeedsDisplay()
}
}
weak var delegate: SwiftColorPickerDataSource?
public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let location = touch.location(in: self)
colorSelectedDelegate?.setStroke(color: colorAtPoint(point: location))
}
public override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let location = touch.location(in: self)
colorSelectedDelegate?.setStroke(color: colorAtPoint(point: location))
}
public override func draw(_ rect: CGRect) {
super.draw(rect)
let lineColor = UIColor.gray
let pS = patternSize()
let w = pS.w
let h = pS.h
for y in 0..<numColorsY
{
for x in 0..<numColorsX
{
let path = UIBezierPath()
let start = CGPoint(x: CGFloat(x)*w+CGFloat(coloredBorderWidth), y: CGFloat(y)*h+CGFloat(coloredBorderWidth))
path.move(to: start);
path.addLine(to: CGPoint(x: start.x+w, y: start.y))
path.addLine(to: CGPoint(x: start.x+w, y: start.y+h))
path.addLine(to: CGPoint(x: start.x, y: start.y+h))
path.addLine(to: start)
path.lineWidth = 0.25
colorForRectAt(x: x,y:y).setFill();
if (showGridLines)
{
lineColor.setStroke()
}
else
{
colorForRectAt(x: x, y: y).setStroke();
}
path.fill();
path.stroke();
}
}
}
private func colorForRectAt(x: Int, y: Int) -> UIColor
{
if let ds = delegate {
return ds.colorForPalletIndex(x: x, y: y, numXStripes: numColorsX, numYStripes: numColorsY)
} else {
var hue:CGFloat = CGFloat(x) / CGFloat(numColorsX)
var fillColor = UIColor.white
if (y==0)
{
if (x==(numColorsX-1))
{
hue = 1.0;
}
fillColor = UIColor(white: hue, alpha: 1.0);
}
else
{
if y < numColorsY / 2 {
//dark
let length = numColorsY / 2
let brightness: CGFloat = CGFloat(y) / CGFloat(length)
fillColor = UIColor(hue: hue, saturation: 1.0, brightness: brightness, alpha: 1.0)
} else if y == numColorsY / 2 {
// normal
fillColor = UIColor(hue: hue, saturation: 1.0, brightness: 1.0, alpha: 1.0)
} else {
// light
let length = numColorsY / 2 - 1
let offset = y - length - 1
let sat:CGFloat = CGFloat(1.0) - CGFloat(offset) / CGFloat(length + 1)
print("sat", sat)
fillColor = UIColor(hue: hue, saturation: sat, brightness: 1.0, alpha: 1.0)
}
}
return fillColor
}
}
func colorAtPoint(point: CGPoint) -> UIColor
{
let pS = patternSize()
let w = pS.w
let h = pS.h
let x = (point.x-CGFloat(coloredBorderWidth))/w
let y = (point.y-CGFloat(coloredBorderWidth))/h
return colorForRectAt(x: Int(x), y:Int(y))
}
private func patternSize() -> (w: CGFloat, h:CGFloat)
{
let width = self.bounds.width-CGFloat(2*coloredBorderWidth)
let height = self.bounds.height-CGFloat(2*coloredBorderWidth)
let w = width/CGFloat(numColorsX)
let h = height/CGFloat(numColorsY)
return (w,h)
}
public override func prepareForInterfaceBuilder()
{
print("Compiled and run for IB")
}
}
使用迈克尔·罗斯的回答,
如果你想通过 Objective-C viewcontroller 使用这个视图,你可以简单地创建一个名为 ColorPickerView 的新 swift 文件,然后将 uiview 添加到 Storyboard 上的 viewcontroller 中,然后选择 ColorPickerView 作为它的类名。然后让你的视图控制器成为名称@“colorIsPicked”的通知观察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateColor) name:@"colorIsPicked" object:nil];
ColorPickerView.swift的代码
class ColorPickerView : UIView {
@objc public lazy var onColorDidChange: ((_ color: UIColor) -> ()) = {
//send a notification for the caller view to update its elements if necessery
NotificationCenter.default.post(name: Notification.Name("colorIsPicked"), object: nil)
}
let saturationExponentTop:Float = 2.0
let saturationExponentBottom:Float = 1.3
let grayPaletteHeightFactor: CGFloat = 0.1
var rect_grayPalette = CGRect.zero
var rect_mainPalette = CGRect.zero
// adjustable
var elementSize: CGFloat = 10.0 {
didSet {
setNeedsDisplay()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
self.clipsToBounds = true
let touchGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.touchedColor(gestureRecognizer:)))
touchGesture.minimumPressDuration = 0
touchGesture.allowableMovement = CGFloat.greatestFiniteMagnitude
self.addGestureRecognizer(touchGesture)
}
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
rect_grayPalette = CGRect(x: 0, y: 0, width: rect.width, height: rect.height * grayPaletteHeightFactor)
rect_mainPalette = CGRect(x: 0, y: rect_grayPalette.maxY,
width: rect.width, height: rect.height - rect_grayPalette.height)
// gray palette
for y in stride(from: CGFloat(0), to: rect_grayPalette.height, by: elementSize) {
for x in stride(from: (0 as CGFloat), to: rect_grayPalette.width, by: elementSize) {
let hue = x / rect_grayPalette.width
let color = UIColor(white: hue, alpha: 1.0)
context!.setFillColor(color.cgColor)
context!.fill(CGRect(x:x, y:y, width:elementSize, height:elementSize))
}
}
// main palette
for y in stride(from: CGFloat(0), to: rect_mainPalette.height, by: elementSize) {
var saturation = y < rect_mainPalette.height / 2.0 ? CGFloat(2 * y) / rect_mainPalette.height : 2.0 * CGFloat(rect_mainPalette.height - y) / rect_mainPalette.height
saturation = CGFloat(powf(Float(saturation), y < rect_mainPalette.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = y < rect_mainPalette.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(rect_mainPalette.height - y) / rect_mainPalette.height
for x in stride(from: (0 as CGFloat), to: rect_mainPalette.width, by: elementSize) {
let hue = x / rect_mainPalette.width
let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
context!.setFillColor(color.cgColor)
context!.fill(CGRect(x:x, y: y + rect_mainPalette.origin.y,
width: elementSize, height: elementSize))
}
}
}
func getColorAtPoint(point: CGPoint) -> UIColor
{
var roundedPoint = CGPoint(x:elementSize * CGFloat(Int(point.x / elementSize)),
y:elementSize * CGFloat(Int(point.y / elementSize)))
let hue = roundedPoint.x / self.bounds.width
// main palette
if rect_mainPalette.contains(point)
{
// offset point, because rect_mainPalette.origin.y is not 0
roundedPoint.y -= rect_mainPalette.origin.y
var saturation = roundedPoint.y < rect_mainPalette.height / 2.0 ? CGFloat(2 * roundedPoint.y) / rect_mainPalette.height
: 2.0 * CGFloat(rect_mainPalette.height - roundedPoint.y) / rect_mainPalette.height
saturation = CGFloat(powf(Float(saturation), roundedPoint.y < rect_mainPalette.height / 2.0 ? saturationExponentTop : saturationExponentBottom))
let brightness = roundedPoint.y < rect_mainPalette.height / 2.0 ? CGFloat(1.0) : 2.0 * CGFloat(rect_mainPalette.height - roundedPoint.y) / rect_mainPalette.height
return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0)
}
// gray palette
else{
return UIColor(white: hue, alpha: 1.0)
}
}
@objc func touchedColor(gestureRecognizer: UILongPressGestureRecognizer){
let point = gestureRecognizer.location(in: self)
let color = getColorAtPoint(point: point)
self.onColorDidChange(color)
}
}