首页 > 解决方案 > Swift 4 - 使用 UIPickerView 自定义 UICollectionReusableView

问题描述

我已经建立了一个UICollectionReusableView像这样的自定义类:

protocol ReviewFooterDelegate: NSObjectProtocol {
    func submitReviewDelegate(text: String, rating: Float)
}

class ReviewFooterCell: UICollectionReusableView {

    @IBOutlet var text: UITextView!
    @IBOutlet var submitButton: UIButton!
    @IBOutlet var rating: CosmosView!
    @IBOutlet var problem: UITextField!
    var reviewFooterDelegate: ReviewFooterDelegate!

    @IBAction func submitButtonPressed(_ sender: Any) {

        reviewFooterDelegate.submitReviewDelegate(text: self.text.text, rating: Float(rating.rating))
    }
}

我想要做的是将 a 添加UITapGestureRecognizerUITextField显示 a UIPickerView,这是我在控制器中使用此自定义类的内容:

在我的viewForSupplementaryElementOfKind方法中:

    let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "ReviewsFooter", for: indexPath) as! ReviewFooterCell
    footerView.reviewFooterDelegate = self
    let problemGesture = UITapGestureRecognizer(target: self, action: #selector(problemTapped))
    footerView.problem.addGestureRecognizer(problemGesture)
    return footerView

这是 problemTapped 方法:

@objc func problemTapped(sender : UITapGestureRecognizer) {

        pickerView.delegate = self
        pickerView.dataSource = self

        let toolBar = UIToolbar()
        toolBar.barStyle = UIBarStyle.default
        toolBar.isTranslucent = true
        toolBar.sizeToFit()

        let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.plain, target: self, action: #selector(ProfessionalReviews.donePicker))
        doneButton.tintColor = UIColor(red: 30.0 / 255.0, green: 53.0 / 255.0, blue: 94.0 / 255.0, alpha: 1.0)

        let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)

        let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItem.Style.plain, target: self, action: #selector(ProfessionalReviews.cancelPicker))
        cancelButton.tintColor = UIColor(red: 30.0 / 255.0, green: 53.0 / 255.0, blue: 94.0 / 255.0, alpha: 1.0)

        toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
        toolBar.isUserInteractionEnabled = true

        /*
        problem.inputAccessoryView = toolBar
        view.addSubview(problem)
        problem.inputView = pickerView
        problem.becomeFirstResponder()
        */
    }

现在我被困在下一步该做什么上,我将如何UITextField在我的自定义类中将其设置为第一响应者?

我想在我的班级而不是我的控制器中设置手势吗?(如果是这样怎么办?)然后在调用我的 donePicker 或 cancelPicker 方法以获取控制器中的返回值时调用另一个委托方法?

标签: iosswiftuicollectionviewuipickerview

解决方案


正如其他人所评论的那样,您不需要 UITapGestureRecognizer 来完成您的要求:

UITextField 显示一个 UIPickerView。

而是将 textField 设置inputView为您的 pickerView。这是执行此操作的代码示例。视图控制器有一个 textField,当被点击时会弹出一个 pickerView。这个项目在github上;请参阅下面的参考资料。

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var pickerTextField: UITextField!

    var pickOption = ["one", "two", "three", "four", "five"]

    var pickerView: UIPickerView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let pickerView = UIPickerView()

        // Assign the pickerView delegate
        pickerView.delegate = self

        // Assign the textField's inputView to be the picker
        pickerTextField.inputView = pickerView
    }

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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickOption.count
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickOption[row]
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        pickerTextField.text = pickOption[row]
    }
}

由于您的 textView 包含在 UICollectionReusableView 中,因此您可以在单元格的类中有一个函数来设置 textView 的 inputView,如下所示:

class ReviewFooterCell: UICollectionReusableView {
    func setTextFieldInputView(pickerView: UIPickerView) {
        problem.inputView = pickerView   
    }    
}

结果类似于此 gif:

替代文字

参考


推荐阅读