当用户触摸已选择的行时如何隐藏 UIPIckerView

Posted

技术标签:

【中文标题】当用户触摸已选择的行时如何隐藏 UIPIckerView【英文标题】:How to hide UIPIckerView when the user touches the row already selected 【发布时间】:2017-05-31 03:13:57 【问题描述】:

我的代码中有多个 UIPickerView,假设用户无意中打开了 PickerView,但想要保持选中同一行,就像我在用户触摸已选择的行时所做的那样,选择器隐藏?

我试过这个:UIPicker detect tap / touch on currently selected row,但我无法让它工作。

--- 编辑---

我会尽量说得更具体些。我是编程和 Swift 语言的初学者。

这是我的 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
    



这段代码效果很好,当我点击“结果”按钮时,它会转到 SecondViewController 并显示照片和描述。

我的困难是,colorPickerView 打开时选择了“蓝色”数据,就像 sizerPickerView 默认打开数据“小”一样。当用户触摸已选择的数据时,我希望 pickerView 关闭/隐藏。

【问题讨论】:

欢迎来到 SO。 我们可以帮助您解决问题或在您提供的代码方面为您提供帮助。如果您无法提供代码,可能没有人可以提供帮助。请发送tour 并阅读help center,了解如何发布问题。 假设您在说“行”时正在谈论 UITableViewCell。因此,要在这里解决您的问题,您可以在行的 contentView 上添加点击手势或使用“didDeselectRowAtIndexPath”委托方法。无论如何,您的问题仍然非常广泛,所以我希望我做对了。 你可以在 didSelectRowAtIndexPath 方法中隐藏它 【参考方案1】:

使类符合UIGestureRecognizerDelegate 协议

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

UITapGestureRecognizer 添加到您的colorPickerView

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

实现UIGestureRecognizerDelegate方法

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

终于实现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
        
    

使用sizerPickerView 复制步骤 2 和 4 以扩展功能。

【讨论】:

我这样做了,但编译器返回了一些错误。 ErrorsCode Line 1Code Line 2我刚刚把colorPickerView换成了barraPickerView,因为它是真名。 我看到我做错了什么,非常感谢,它工作得很好。

以上是关于当用户触摸已选择的行时如何隐藏 UIPIckerView的主要内容,如果未能解决你的问题,请参考以下文章

当用户滑动并点击手指(使用触摸手势)时如何隐藏所有 CollectionViewCell?

选择时如何从表格视图中隐藏行

当用户触摸 uiscrollview 时隐藏表格

当用户在功能性反应组件中使用触摸屏时,用按钮隐藏 div

android:当用户触摸片段外部时,我如何关闭片段?

表中每一行的不同菜单项