简单快捷的颜色选择器popover(iOS)(Simple swift color picker popover (iOS))

IPhone IT屋
百度翻译此文   有道翻译此文
问 题

Is there is a simple way to implement a color picker popover in swift? Are there any built-in libraries or UI elements that I could leverage for this purpose? I saw some color pickers written in objective-c, but they were several years old and I was wondering if there was something more recent.

解决方案

Here's one I made which is as simple as it gets. It's just a lightweight UIView that allows you to specify the element size in case you want blocked regions (elementSize > 1). It draws itself in interface builder so you can set element size and see the consequences. Just set one of your views in interface builder to this class and then set yourself as a delegate. It will tell you when someone either taps or drags on it and the uicolor at that location. It will draw itself to its own bounds and there's no need for anything other than this class, no image required.

Element size=1 (Default) element size=1

Element size=10
element size=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(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)
        }        
    }
}

本文地址:IT屋 » Simple swift color picker popover (iOS)

问 题

是否有一种简单的方法可以在swift中实现颜色选择器弹出窗口?是否有可用于此目的的内置库或UI元素?我看到一些用objective-c写的颜色选择器,但它们已经好几年了,我想知道是否有更新的东西。


解决方案

这是我制作的一个很简单的。它只是一个轻量级的UIView,允许您指定元素大小,以防您想要阻塞区域(elementSize> 1)。它在界面构建器中绘制,因此您可以设置元素大小并查看结果。只需将界面构建器中的一个视图设置为此类,然后将自己设置为委托。当有人点击或拖动它并在该位置使用uicolor时它会告诉你。它会将自己绘制到自己的边界,除了这个类之外不需要任何其他东西,不需要图像。



元素大小= 1(默认)



元素大小= 10

“element



 内部协议HSBColorPickerDelegate:NSObjectProtocol {
func HSBColorColorPickerTouched(发送者:HSBColorPicker,颜色:UIColor,点:CGPoint,状态:UIGestureRecognizerState)
}

@IBDesignable
类HSBColorPicker:UIView {

弱内部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)
}

重写init(frame:CGRect){
super.init(frame:frame)
initialize()
}

必需init?(编码器aDecoder: NSCoder){
super.init(编码器:aDecoder)
initialize()
}

覆盖func draw(_ rect:CGRect){
let context = UIGraphicsGetCu rrentContext()
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
饱和度= CGFloat(powf(Float(饱和度),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(色调:色调,饱和度:饱和度,亮度:亮度,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) (饱和度),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
返回UIColor(色调:色调,饱和度:饱和度,亮度:亮度,alpha:1.0)
}

func getPointForColor(颜色:UIColor) - > CGPoint {
var hue:CGFloat = 0.0
var saturation:CGFloat = 0.0
var brightness:CGFloat = 0.0
color.getHue(& hue,saturation:& saturation,亮度:& brightness,alpha:nil);

var yPos:CGFloat = 0
let halfHeight =(self.bounds.height / 2)
if(brightness> = 0.99){
let percentageY = powf(Float(饱和度),1.0 / saturationExponentTop)
yPos = CGFloat(percentageY)* halfHeight
} else {
//使用亮度获得Y
yPos = halfHeight + halfHeight *(1.0 - 亮度)
}
让xPos = hue * self.bounds.width
返回CGPoint(x:xPos,y:yPos)
}

@objc func touchingColor(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)
}
}
}

本文地址:IT屋 » 简单快捷的颜色选择器popover(iOS)

官方微信
扫一扫关注IT屋
微信公众号搜索 “ IT屋 ” ,选择关注
与百万开发者在一起