0

I have in my code more than one UIPickerView, and let's say that the user opens the PickerView unintentionally, but wants to keep the same row selected, as I do for when the user touches the already selected row, the selector hide?

I tried this: UIPicker detect tap / touch on currently selected row, but I could not make it work.

--- edit ---

I'll try to be more specific. I'm a beginner in programming and the Swift language.

This is my ViewController.swift

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

@IBOutlet weak var colorLabel: UILabel!
@IBOutlet weak var sizeLabel: UILabel!

@IBOutlet weak var colorButton: UIButton!
@IBOutlet weak var sizeButton: UIButton!

@IBOutlet weak var resultButton: UIButton!

@IBOutlet weak var colorPickerView: UIPickerView! = UIPickerView()
@IBOutlet weak var sizePickerView: UIPickerView! = UIPickerView()

var colorPickerData = ["Blue", "Red"]
var sizePickerData = ["Small", "Big"]

var descri = String()
var resultadoImagem = UIImage()

override func viewDidLoad() {
    super.viewDidLoad()


    colorPickerView.isHidden = true
    sizePickerView.isHidden = true


    self.colorPickerView.delegate = self
    self.colorPickerView.dataSource = self

    self.sizePickerView.delegate = self
    self.sizePickerView.dataSource = self


    colorLabel.text = colorPickerData[0]
    sizeLabel.text = sizePickerData[0]
}

override func didReceiveMemoryWarning() {

    super.didReceiveMemoryWarning()

}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if pickerView.tag == 1 {
        return colorPickerData.count
    } else if pickerView.tag == 2 {
        return sizePickerData.count
    }
    return 0
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if pickerView.tag == 1 {
        return "\(colorPickerData[row])"
    } else if pickerView.tag == 2 {
        return "\(sizePickerData[row])"
    }
    return ""
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if pickerView.tag == 1 {
        colorLabel.text = colorPickerData[row]
        colorPickerView.isHidden = true
    } else if pickerView.tag == 2 {
        sizeLabel.text = sizePickerData[row]
        sizePickerView.isHidden = true
    }
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    colorPickerView.isHidden = true
    sizePickerView.isHidden = true
}

@IBAction func colorButton(_ sender: Any) {
    colorPickerView.isHidden = !colorPickerView.isHidden
}

@IBAction func sizeButton(_ sender: Any) {
    sizePickerView.isHidden = !sizePickerView.isHidden
}

@IBAction func resultButton(_ sender: Any) {
    if (colorLabel.text == "Blue")
        && (sizeLabel.text == "Big") { resultadoImagem = UIImage(named: "blue-big.png")!; descri = "BLUE"}
    else if (colorLabel.text == "Blue")
        && (sizeLabel.text == "Small") { resultadoImagem = UIImage(named: "blue-small.png)!; descri = "BLUE"}
    else if (colorLabel.text == "Red")
        && (sizeLabel.text == "Big") { resultadoImagem = UIImage(named: "red-big.png")!; descri = "RED"}
    else if (colorLabel.text == "Red")
        && (sizeLabel.text == "Small") { resultadoImagem = UIImage(named: "red-small.png")!; descri = "RED"}

    self.performSegue(withIdentifier: "resultSegue", sender: nil)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "resultSegue" {
        let DestViewController : SecondViewController = segue.destination as! SecondViewController

    DestViewController.descText = descri
    DestViewController.resultPhoto = resultadoImagem
    }
}

}

This code works great, when I hit the "Result" button it goes to the SecondViewController and shows photo and description.

My difficulty is, the colorPickerView opens with the data "Blue" selected, just as the sizerPickerView opens with the data "Small" by default. I want pickerView to close/hide when the user touches the data that is already selected.

  • 1
    Welcome to SO. **We are here to help you troubleshoot or help you in the codes you provide. If you are not able to provide code no one might be able to help.** Please take a [tour](https://stackoverflow.com/help) and read the [help center](https://stackoverflow.com/help) on how to post questions. – Syfer May 31 '17 at 03:44
  • Assuming you are talking about UITableViewCell when you say 'row'. So to solve your problem here you could either add tap gesture on contentView of the row or use the 'didDeselectRowAtIndexPath' delegate method. Anyways your question is still very broad so I hope I got it right. – Shubham Naik May 31 '17 at 04:20
  • 1
    you can hide it on didSelectRowAtIndexPath method – Anil Kukadeja May 31 '17 at 04:52

1 Answers1

2

Conform class to UIGestureRecognizerDelegate protocol

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UIGestureRecognizerDelegate { 
    // ... 
}

Add a UITapGestureRecognizer to your colorPickerView

let tap = UITapGestureRecognizer(target: self, action: #selector(self.tapAction(_:)))
tap.cancelsTouchesInView = false
tap.delegate = self
colorPickerView.addGestureRecognizer(tap)

Implement UIGestureRecognizerDelegate method

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

Finally implement tapAction

func tapAction(_ tapRecognizer:UITapGestureRecognizer) {
    if tapRecognizer.state == .ended {
        let rowHeight : CGFloat  = colorPickerView.rowSize(forComponent: 0).height
        let selectedRowFrame: CGRect = colorPickerView.bounds.insetBy(dx: 0.0, dy: (colorPickerView.frame.height - rowHeight) / 2.0)
        let userTappedOnSelectedRow = selectedRowFrame.contains(tapRecognizer.location(in: colorPickerView))
        if (userTappedOnSelectedRow){
            let selectedRow = colorPickerView.selectedRow(inComponent: 0)
            //do whatever you want here
        }
    }
}

Replicate steps 2 and 4 using sizerPickerView to extend functionality.

Jože Ws
  • 1,754
  • 17
  • 12
  • I did this, but the compiler returned me some errors. [Errors](https://i.stack.imgur.com/mycpK.png) [Code Line 1](https://i.stack.imgur.com/RCvhE.png) [Code Line 2](https://i.stack.imgur.com/Rz4oA.png) I just replaced colorPickerView for barraPickerView because it's the real name. – Gabriel Henrique Jun 01 '17 at 00:00
  • I saw what I was doing wrong, thank you so much, it worked perfectly. – Gabriel Henrique Jun 01 '17 at 00:15