tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath)当我将UITapGestureRecognizer添加到我的自定义UITableViewCell时,它不起作用

时间:2016-11-14 07:05:11

标签: ios swift uitableview swift3

我手边有一个非常原始的问题,就是当我将自定义手势识别器添加到我的自定义单元格中时,我无法调用didSelectRowAt方法。

我的代码如下:

import UIKit

class LanguageViewController: UIViewController {

    @IBOutlet weak var titleLabel: AvenirUILabel!
    @IBOutlet weak var backButton: UIButton!
    @IBOutlet weak var submitButton: PinkUIButton!
    @IBOutlet weak var addLanguageButton: UIButton!
    @IBOutlet weak var addAnotherLanguageLabel: UILabel!
    @IBOutlet weak var tableView: UITableView!

    @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!

    var numberOfLanguagesSpoken = 2
    var pickersStartHeight: CGFloat!
    let downArrowImage = UIImage(named: "arrow_drop_down")
    let BGColor = UIColor.white.withAlphaComponent(0.1)
    var tag = 1001
    var selectedCellHeight: CGFloat = 88.0
    var unselectedCellHeight: CGFloat = 44.0
    var selectedCellIndexPath: IndexPath?
    let languages = ["Akan", "Amharic", "Arabic", "Assamese", "Awadhi", "Azerbaijani", "Balochi", "Belarusian", "Bengali", "Bhojpuri", "Burmese", "Cebuano", "Chewa", "Chhattisgarhi", "Chittagonian", "Czech", "Deccan", "Dhundhari", "Dutch", "Eastern Min", "English", "French", "Fula", "Gan Chinese", "German", "Greek", "Gujarati", "Haitian Creole", "Hakka", "Haryanvi", "Hausa", "Hiligaynon/Ilonggo", "Hindi ", "Hmong", "Hungarian", "Igbo", "Ilocano", "Italian", "Japanese", "Javanese", "Jin", "Kannada", "Kazakh", "Khmer", "Kinyarwanda", "Kirundi", "Konkani", "Korean", "Kurdish", "Madurese", "Magahi", "Maithili", "Malagasy", "Malay", "Malayalam", "Mandarin", "Marathi", "Marwari", "Mossi", "Nepali", "Northern Min", "Odia", "Oromo", "Pashto", "Persian", "Polish", "Portuguese", "Punjabi", "Quechua", "Romanian", "Russian", "Saraiki", "Serbo-Croatian", "Shona", "Sindhi", "Sinhalese", "Somali", "Southern Min", "Spanish", "Sundanese", "Swedish", "Sylheti", "Tagalog/Filipino", "Tamil", "Telugu", "Thai", "Turkish", "Turkmen", "Ukrainian", "Urdu", "Uyghur", "Uzbek", "Vietnamese", "Wu", "Xhosa", "Xiang ", "Yoruba", "Yue ", "Zhuang", "Zulu"]

    var proficiency = ["Basic","Conversational","Proficient","Fluent","Native"]

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = backgroundTint

        //  initial set up

        let height = self.view.bounds.height

        titleLabel.textColor = .white

        backButton.addTarget(self, action: #selector(goBack), for: .allTouchEvents)

        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(LanguageProficiencyTableViewCell.self, forCellReuseIdentifier: "Language")
        tableView.backgroundColor = backgroundTint
        tableView.allowsSelection = true
        tableViewHeightConstraint.constant = 2*height/9


        addLanguageButton.tintColor = .white
        addLanguageButton.addTarget(self, action: #selector(addNewLanguage), for: .allTouchEvents)

        addAnotherLanguageLabel.textColor = .white

        submitButton.addTarget(self, action: #selector(submitChanges), for: .allEvents)
    }

    override func viewWillLayoutSubviews() {
        unselectedCellHeight = self.view.bounds.height/9
        selectedCellHeight = CGFloat(unselectedCellHeight * 2.0)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func goBack() {
        self.dismiss(animated: true, completion: nil)
    }

    func submitChanges() {
        self.dismiss(animated: true) {
            //
        }
    }

    func addNewLanguage() {
        numberOfLanguagesSpoken += 1
        UIView.animate(withDuration: 0.5) {
            //
        }
    }

    /*
     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     // Get the new view controller using segue.destinationViewController.
     // Pass the selected object to the new view controller.
     }
     */

}
extension LanguageViewController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return numberOfLanguagesSpoken
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Language", for: indexPath) as! LanguageProficiencyTableViewCell
        cell.parentVC = self
        cell.backgroundColor = .clear
        cell.languages = self.languages
        cell.proficiency = self.proficiency
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if selectedCellIndexPath == indexPath {
            return selectedCellHeight
        } else {
            return unselectedCellHeight
        }
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        //
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if selectedCellIndexPath != nil && selectedCellIndexPath == indexPath as IndexPath {
            selectedCellIndexPath = nil
        } else {
            selectedCellIndexPath = indexPath as IndexPath
        }

        tableView.beginUpdates()
        tableView.endUpdates()

        if selectedCellIndexPath != nil {
            // This ensures, that the cell is fully visible once expanded
            tableView.scrollToRow(at: indexPath as IndexPath, at: .none, animated: true)
        }
    }

    func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        return indexPath
    }
}

import UIKit

class LanguageProficiencyTableViewCell: UITableViewCell {

    let languageLabel = IndentedTextUILabel()
    var languagePicker = UIPickerView()
    weak var parentVC: LanguageViewController!
    var cellHeight: CGFloat = 80
    var open = false
    var languages = [""]
    var proficiency = [""]
    var pickedLanguage = ""
    var pickedProficiency = ""

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        self.contentView.addSubview(languageLabel)
        self.contentView.addSubview(languagePicker)
        self.contentView.backgroundColor = .clear
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }

    override func layoutSubviews() {

        let width = self.bounds.width
        let height = cellHeight
        let BGColor = UIColor.white.withAlphaComponent(0.1)

        languageLabel.frame = CGRect(x: 0.0, y: 1.0, width: width, height: height - 1.0)
        languageLabel.textColor = .white
        languageLabel.backgroundColor = BGColor
        languageLabel.text = "Language(Proficiency)"
        languageLabel.leftInset = 25.0
        let downArrow = UIButton()
        let downArrowImage = UIImage(named: "arrow_drop_down")
        downArrow.setImage(downArrowImage, for: .normal)
        downArrow.center.y = height/2
        downArrow.center.x = 4 * width/5
        languageLabel.addSubview(downArrow)

        let tap = UITapGestureRecognizer(target: self, action: #selector(cellTapped))
        self.addGestureRecognizer(tap)

        languagePicker.frame = CGRect(x: 0.0, y: self.cellHeight + 1.0, width: self.bounds.width, height: 0.0)
        languagePicker.delegate = self
        languagePicker.dataSource = self
        languagePicker.backgroundColor = UIColor.white.withAlphaComponent(0.05)
        languagePicker.selectRow(20, inComponent: 0, animated: true)

        let backGroundView = UIView(frame: CGRect(x: 0.0, y: 1.0, width: width, height: height - 1.0))
        backGroundView.backgroundColor = .clear
        self.selectedBackgroundView = backGroundView
    }

    func cellTapped() {
        UIView.animate(withDuration: 0.2, animations: {
            if !self.open {
                self.languagePicker.frame.size.height = self.cellHeight - 2.0
            } else {
                self.languagePicker.isHidden = true
            }
            }, completion: { (_) in
                if self.open {
                    self.languagePicker.frame.size.height = 0.0
                    self.languagePicker.isHidden = false
                }
                self.open = !self.open
        })
    }
}

2 个答案:

答案 0 :(得分:0)

它不会起作用,因为点击手势会点击其自身,而不会将点击发送到其下方的视图。

您可以通过点击手势发送点击以通过

传递给背景视图
mySwipeGesture.cancelsTouchesInView = false

How to pass a 'tap' to UIButton that is underneath UIView with UISwipeGestureRecognizer?

中所述

此外,如果您使用轻击手势只是为了解雇键盘,您可以在tableView的didSelectAt方法中执行此操作,并在解除该方法中的键盘后执行任何其他操作。

答案 1 :(得分:0)

我正在做的事情就像你做的一样,而且对我有用。

您必须在 TableViewCell 类中添加手势识别器,但在设置单元格时,必须从 Controller 类添加。

像这样:

class LanguageViewController: UIViewController {

    @IBOutlet weak var titleLabel: AvenirUILabel!
    @IBOutlet weak var backButton: UIButton!
    @IBOutlet weak var submitButton: PinkUIButton!
    @IBOutlet weak var addLanguageButton: UIButton!
    @IBOutlet weak var addAnotherLanguageLabel: UILabel!
    @IBOutlet weak var tableView: UITableView!

    @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!

    var numberOfLanguagesSpoken = 2
    var pickersStartHeight: CGFloat!
    let downArrowImage = UIImage(named: "arrow_drop_down")
    let BGColor = UIColor.white.withAlphaComponent(0.1)
    var tag = 1001
    var selectedCellHeight: CGFloat = 88.0
    var unselectedCellHeight: CGFloat = 44.0
    var selectedCellIndexPath: IndexPath?
    let languages = ["Akan", "Amharic", "Arabic", "Assamese", "Awadhi", "Azerbaijani", "Balochi", "Belarusian", "Bengali", "Bhojpuri", "Burmese", "Cebuano", "Chewa", "Chhattisgarhi", "Chittagonian", "Czech", "Deccan", "Dhundhari", "Dutch", "Eastern Min", "English", "French", "Fula", "Gan Chinese", "German", "Greek", "Gujarati", "Haitian Creole", "Hakka", "Haryanvi", "Hausa", "Hiligaynon/Ilonggo", "Hindi ", "Hmong", "Hungarian", "Igbo", "Ilocano", "Italian", "Japanese", "Javanese", "Jin", "Kannada", "Kazakh", "Khmer", "Kinyarwanda", "Kirundi", "Konkani", "Korean", "Kurdish", "Madurese", "Magahi", "Maithili", "Malagasy", "Malay", "Malayalam", "Mandarin", "Marathi", "Marwari", "Mossi", "Nepali", "Northern Min", "Odia", "Oromo", "Pashto", "Persian", "Polish", "Portuguese", "Punjabi", "Quechua", "Romanian", "Russian", "Saraiki", "Serbo-Croatian", "Shona", "Sindhi", "Sinhalese", "Somali", "Southern Min", "Spanish", "Sundanese", "Swedish", "Sylheti", "Tagalog/Filipino", "Tamil", "Telugu", "Thai", "Turkish", "Turkmen", "Ukrainian", "Urdu", "Uyghur", "Uzbek", "Vietnamese", "Wu", "Xhosa", "Xiang ", "Yoruba", "Yue ", "Zhuang", "Zulu"]

    var proficiency = ["Basic","Conversational","Proficient","Fluent","Native"]

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = backgroundTint

        //  initial set up

        let height = self.view.bounds.height

        titleLabel.textColor = .white

        backButton.addTarget(self, action: #selector(goBack), for: .allTouchEvents)

        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(LanguageProficiencyTableViewCell.self, forCellReuseIdentifier: "Language")
        tableView.backgroundColor = backgroundTint
        tableView.allowsSelection = true
        tableViewHeightConstraint.constant = 2*height/9


        addLanguageButton.tintColor = .white
        addLanguageButton.addTarget(self, action: #selector(addNewLanguage), for: .allTouchEvents)

        addAnotherLanguageLabel.textColor = .white

        submitButton.addTarget(self, action: #selector(submitChanges), for: .allEvents)
    }

    override func viewWillLayoutSubviews() {
        unselectedCellHeight = self.view.bounds.height/9
        selectedCellHeight = CGFloat(unselectedCellHeight * 2.0)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func goBack() {
        self.dismiss(animated: true, completion: nil)
    }

    func submitChanges() {
        self.dismiss(animated: true) {
            //
        }
    }

    func addNewLanguage() {
        numberOfLanguagesSpoken += 1
        UIView.animate(withDuration: 0.5) {
            //
        }
    }

    /*
     // MARK: - Navigation

     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     // Get the new view controller using segue.destinationViewController.
     // Pass the selected object to the new view controller.
     }
     */

}
extension LanguageViewController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return numberOfLanguagesSpoken
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Language", for: indexPath) as! LanguageProficiencyTableViewCell
        cell.parentVC = self
        cell.backgroundColor = .clear
        cell.languages = self.languages
        cell.proficiency = self.proficiency
        let tap = UITapGestureRecognizer(target: self, action: #selector("cellTapped:"))
        cell.addGestureRecognizer(tap)
        return cell
    }

    //Change here you can't call languagePicker with self but you have to get it from the object tapped that in your case is you cell
    func cellTapped(recognizer: UITapGestureRecognizer) {
        UIView.animate(withDuration: 0.2, animations: {
            if !self.open {
                self.languagePicker.frame.size.height = self.cellHeight - 2.0
            } else {
                self.languagePicker.isHidden = true
            }
            }, completion: { (_) in
                if self.open {
                    self.languagePicker.frame.size.height = 0.0
                    self.languagePicker.isHidden = false
                }
                self.open = !self.open
        })
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if selectedCellIndexPath == indexPath {
            return selectedCellHeight
        } else {
            return unselectedCellHeight
        }
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        //
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if selectedCellIndexPath != nil && selectedCellIndexPath == indexPath as IndexPath {
            selectedCellIndexPath = nil
        } else {
            selectedCellIndexPath = indexPath as IndexPath
        }

        tableView.beginUpdates()
        tableView.endUpdates()

        if selectedCellIndexPath != nil {
            // This ensures, that the cell is fully visible once expanded
            tableView.scrollToRow(at: indexPath as IndexPath, at: .none, animated: true)
        }
    }

    func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        return indexPath
    }
}

import UIKit

class LanguageProficiencyTableViewCell: UITableViewCell {

    let languageLabel = IndentedTextUILabel()
    var languagePicker = UIPickerView()
    weak var parentVC: LanguageViewController!
    var cellHeight: CGFloat = 80
    var open = false
    var languages = [""]
    var proficiency = [""]
    var pickedLanguage = ""
    var pickedProficiency = ""

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        self.contentView.addSubview(languageLabel)
        self.contentView.addSubview(languagePicker)
        self.contentView.backgroundColor = .clear
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }

    override func layoutSubviews() {

        let width = self.bounds.width
        let height = cellHeight
        let BGColor = UIColor.white.withAlphaComponent(0.1)

        languageLabel.frame = CGRect(x: 0.0, y: 1.0, width: width, height: height - 1.0)
        languageLabel.textColor = .white
        languageLabel.backgroundColor = BGColor
        languageLabel.text = "Language(Proficiency)"
        languageLabel.leftInset = 25.0
        let downArrow = UIButton()
        let downArrowImage = UIImage(named: "arrow_drop_down")
        downArrow.setImage(downArrowImage, for: .normal)
        downArrow.center.y = height/2
        downArrow.center.x = 4 * width/5
        languageLabel.addSubview(downArrow)

        languagePicker.frame = CGRect(x: 0.0, y: self.cellHeight + 1.0, width: self.bounds.width, height: 0.0)
        languagePicker.delegate = self
        languagePicker.dataSource = self
        languagePicker.backgroundColor = UIColor.white.withAlphaComponent(0.05)
        languagePicker.selectRow(20, inComponent: 0, animated: true)

        let backGroundView = UIView(frame: CGRect(x: 0.0, y: 1.0, width: width, height: height - 1.0))
        backGroundView.backgroundColor = .clear
        self.selectedBackgroundView = backGroundView
    }
}