2016-09-23 8 views
4

Ich arbeite an einer App, die mit einem Arduino kommuniziert, um RGB-LED-Lichtleisten zu steuern. Ich versuche, einen Farbwähler zu implementieren, wo Sie ein Bild eines Farbspektrums berühren und den UIColor des Pixels erhalten, das berührt wurde.IOS Farbwähler in Swift 3.0

Ich möchte, dass ein Benutzer in der Lage ist, überall auf dem Farbspektrum Bild zu berühren und die Farbe zu der Farbe ändern, die sie berühren. dazu brauche ich entweder die RGB-Zahlen oder die UIColor des Pixels, das sie berühren.

Ich habe den folgenden Code gefunden, den ich versucht habe, ohne Erfolg zu implementieren. Hier ist die ursprüngliche Beschreibung des Autors:

"Hier ist eine, die ich gemacht, die so einfach ist wie es geht. Es ist nur eine leichte UIView, die Sie die Elementgröße für den Fall, dass Sie blockierte Regionen (elementSize> 1) Zeichnet sich selbst im Interface Builder auf, so dass Sie die Elementgröße festlegen und die Konsequenzen sehen können Setzen Sie einfach eine Ihrer Ansichten im Interface Builder auf diese Klasse und stellen Sie sich dann selbst als Delegat ein Sie wird informiert, wenn jemand darauf klickt oder zieht An diesem Ort wird er uicolor sein, er wird sich selbst in seine eigenen Grenzen zurückziehen, und nichts anderes als diese Klasse wird benötigt, kein Bild wird benötigt. "

import UIKit 

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, 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.locationInView(self) 
    let color = getColorAtPoint(point) 

    self.delegate?.HSBColorColorPickerTouched(self, color: color, point: point, state:gestureRecognizer.state) 
} 
} 

Ich bin nicht sicher, wie dieser Code in swift 3.0 funktioniert. Ich habe es so gut portiert ich kann, aber ich bekomme die folgende Fehlermeldung, dass ich nicht sicher bin, wie zu beheben:

enter image description here

und

enter image description here

für den ersten Fehler, den ich zu haben scheinen löste es durch Ändern des Codes zu den folgenden, aber ich bin mir nicht sicher, ob dies korrekt ist

private func initialize() { 
    self.clipsToBounds = true 
    let touchGesture = UILongPressGestureRecognizer(target: self, action: #selector(HSBColorPicker.touchedColor(gestureRecognizer:))) 
    touchGesture.minimumPressDuration = 0 
    touchGesture.allowableMovement = CGFloat.greatestFiniteMagnitude 
    self.addGestureRecognizer(touchGesture) 
} 

Wie für die zweite err ors ich bin nur nicht sicher, wie man auf schreiten setzt. (von: bis:, durch :)

Hier ist mein Versuch, es zu swift 3.0 zu portieren.

import UIKit 

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(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 (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) 
      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) 
} 
} 

Ich würde wirklich jede Hilfe schätzen, die Sie alle zu bieten haben. Ich bin auch offen für völlig andere Vorschläge, wenn Sie eine bessere Möglichkeit haben, mein ursprüngliches Ziel eines Farbwählers zu erreichen, den der Benutzer anfassen kann!

Antwort

1

1) Für diese Zeile Code zu arbeiten:

let touchGesture = UILongPressGestureRecognizer(target: self, action: #selector(HSBColorPicker.touchedColor(_:))) 

Sie benötigen _ Charakter auf den Parameter in dieser Methode unterstreichen vorangestellt wird:

func touchedColor(_ gestureRecognizer: UILongPressGestureRecognizer){ } 

2) Wenn Bei Verwendung von stride lautet die richtige Syntax:

for y in stride(from: 0, to: rect.height, by: elementSize) { 

So voll for-cycle mit zusätzlichen Korrekturen in Swift 3-Version sollte wie folgt aussehen:

for y in stride(from: 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 in stride(from: 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)) 
    } 
} 
+0

Perfect! Genau das hat mich aufgehängt! Noch eine Frage, ich habe eine Variable für Rot, Grün und Blau. Wie würde ich diese Variablen basierend auf dem obigen Code auf die Farbe einstellen, die berührt wird? – BLF0005

+0

Ich nehme an, du meinst, let color = UIColor() line: Also einfach 'let color = UIColor (rot: grün: weiß:)' Methode. Und hat meine Antwort dir geholfen? :) – pedrouan