有没有一种简单的方法来实现一个颜色选择器popover在迅捷?是否有任何内置的图书馆或UI元素,我可以为此目的利用?我看到一些用Objective-C写的颜色选择器,但是他们几岁,我想知道是否有更新的东西.
解决方法
这是我所做的一样简单.它只是一个轻量级的UIView,允许您指定元素大小,以防您想要阻止区域(elementSize> 1).它将自身绘制在界面构建器中,以便您可以设置元素大小并查看后果.只需将界面构建器中的一个视图设置为此类,然后将自己设置为委托.有人会在某人点击或拖动它,并在那个位置使用uicolor来告诉你.它将自己画成自己的界限,除了这个课外,没有任何需要,没有形象.
元素大小= 1(默认)
元素大小= 10
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(HSBColorPicker.touchedColor(_:)))
touchGesture.minimumPressDuration = 0
touchGesture.allowableMovement = CGFloat.max
self.addGestureRecognizer(touchGesture)
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
for y in (0 as CGFloat).stride(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 (0 as CGFloat).stride(to: rect.width,by: elementSize) {
let hue = x / rect.width
let color = UIColor(hue: hue,saturation: saturation,brightness: brightness,alpha: 1.0)
CGContextSetFillColorWithColor(context,color.CGColor)
CGContextFillRect(context,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,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.locationInView(self)
let color = getColorAtPoint(point)
self.delegate?.HSBColorColorPickerTouched(self,color: color,point: point,state:gestureRecognizer.state)
}
}