Alternative platin solution ch 19 with color picker

I like to present a different approach for the integration of a color panel. I wanted to have a color picker, and so I searched in the community and found one here (http://theappspace.com/custom-color-picker-in-swift/). I had to convert from swift 2 to 3. The final application was done in Xcode beta 9.5 starting from the silver Touchtracker.

I created a swift file with the ColorPicker class. There is also a protocol, which contains a method, which we will use in the DrawView. We will change the ColorPicker script later. Now open the storyboard and place a view and two buttons (SELECT and CANCEL button). Adjust the size of the view to your needs like width of 320 and height of 100 and set the custom class in the identity inspector to ColorPicker. Place the two buttons into a horizontal stackview with “fill proportionally”. Then place the stackview and the view into a new vertical stackview with the buttons on top. In the attributes inspector set fill proportionally and spacing to 10. Place the stackview manually close to the top and center it. Then open new constraints for the ColorPicker view and set the height to 100. Now open new constraints for the main stackview and click on the top, right and left constraints. Don’t change the total value of right and left. If right is 10 and left is 8, set both to 9. Add 3 constraints. Make this stackview hidden in the attributes inspector.

Now the scripts need to be adjusted. First open the ColorPicker class and delete the touchesBegan, Moved and Ended functions, because the same functions are overridden in the DrawView class. Then change the updateColor function. We have to call this function now from the DrawView class.

func updateColor(_ curSelectionX: CGFloat){
        selectedColor = UIColor(hue: (curSelectionX / self.frame.size.width), saturation: 1.0, brightness: 1.0, alpha: 1.0)
        self.delegate.pickedColor!(selectedColor)
        self.setNeedsDisplay()
    }

Now change Line,swift and add

var lineColor: UIColor = UIColor.black

Now open DrawView.swift. Change the class to add colorDelegate, which allows us to get the color from the picker.

class DrawView: UIView, colorDelegate, UIGestureRecognizerDelegate {

Add variables for the storyboard objects and connect the main stackview with “holdViews”, the colorPicker view and the two buttons. The other variables we need later.

// Objects from the storyboard connected
    @IBOutlet var holdViews: UIStackView!
    @IBOutlet var colorPicker: ColorPicker!
    @IBOutlet var colorView: UIButton!
    @IBOutlet var cancelNewColor: UIButton!
    
    // Var to hold the color from the colorpicker
    var selectedColor: UIColor = UIColor.black
    var curSelectionYmin: Int = 0
    var curSelectionYmax: Int = 0

Make longPressRecognizer accessible to the whole class.

`var longPressRecognizer: UILongPressGestureRecognizer!`

Add the swipe up script.

        let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(DrawView.swipeup(gesture:)))
        swipeUp.direction = .up
        // See my comment at the bottom.
        swipeUp.numberOfTouchesRequired = 2
        addGestureRecognizer(swipeUp)

Then add this function for the swipe up gesture. I added @objc to all button type functions, which is required in swift 4.

    @objc func swipeup(gesture: UISwipeGestureRecognizer) -> Void {
        if gesture.direction == UISwipeGestureRecognizerDirection.up {
            print("Swipe Up")
            
            currentLines.removeAll()
            colorPicker.delegate = self;
            colorView.setTitle("SELECT", for: .normal)
            colorView.backgroundColor = selectedColor
            colorView.addTarget(self, action: #selector(setColor(_:)), for: UIControlEvents.touchUpInside)
            cancelNewColor.setTitle("CANCEL", for: .normal)
            cancelNewColor.addTarget(self, action: #selector(setColor(_:)), for: UIControlEvents.touchUpInside)
            
            // Define the y coordinates for the colorpicker
            curSelectionYmin = Int(colorPicker.frame.minY + 10 + colorView.frame.height)
            curSelectionYmax = Int(colorPicker.frame.maxY + 10 + colorView.frame.height)
            
            // Making the colorpicker visible
            holdViews.isHidden = false
            
            // Get color by a long press
            moveRecognizer.isEnabled = false
            longPressRecognizer.isEnabled = false
        }
    }

Add the next two functions. “pickedColor” connects to the ColorPicker class.

    func pickedColor(_ color: UIColor) {
        // Setting the color
        colorView.backgroundColor = color;
    }
    
    @objc func setColor(_ sender: UIButton) {
        print("Color selected")
        // Change color only with SELECT button
        if sender.currentTitle == "SELECT" {
            selectedColor = colorView.backgroundColor!
        }
        holdViews.isHidden = true
        
        // Restore original gestures
        longPressRecognizer.isEnabled = true
        moveRecognizer.isEnabled = true
    }

Change the stroke function.

func stroke(_ Line: Line, color: UIColor = .black) {

Change inside the function.

            // When change color of moving lines or currentLines 
            if color != .black {
                color.setStroke()
            } else {
                Line.lineColor.setStroke()
            }
        
Change draw.

	override func draw(_ rect: CGRect) {
        // Draw finished lines
        for line in finishedLines {
            stroke(line)
        }
    
        // Draw current lines
        for (_, line) in currentLines {
            stroke(line, color: .red)
        }
        
        if let index = selectedLineIndex {
            let selectedLine = finishedLines[index]
            stroke(selectedLine, color: .green)
        }
    }

Add this to all touches classes.

    let touch = touches.first
        if holdViews.isHidden == false {
            let coltouch = Int((touch?.location(in: self).y)!)
            if coltouch <= curSelectionYmax && coltouch >= curSelectionYmin {
                let curSelectionX = ((touch?.location(in: self).x)! - holdViews.frame.minX)
                colorPicker.updateColor(curSelectionX)
            }
        } else {
            for touch in touches {

Change the newline to this in touchesBegan.

let newLine = Line(begin: location, end: location, lineColor: selectedColor)

When you test the app now you will see the color picker. Press a bit longer and release on a color for the colorView to change. To be honest I never got any three finger swipe to work on the simulator even after activating the three finger drag for the trackpad. So I tested everything with two fingers (option + shift).