Swift 4 - Пользовательский UICollectionReusableView с UIPickerView - PullRequest
0 голосов
/ 01 июля 2019

Я создал собственный класс 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))
    }
}

Я пытаюсь добавить UITapGestureRecognizer к UITextField, чтобы отобразить 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 для получения возвращаемого значения в контроллере?

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Как прокомментировали другие, вам не нужен UITapGestureRecognizer для выполнения того, что вы просите:

UITextField для отображения UIPickerView.

Вместо этого установите inputView textField на свой 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, у вас может быть функция в классе вашей ячейки для установки inputView textView следующим образом:

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

Результат похож на этот GIF:

alt text

Ссылки

0 голосов
/ 08 июля 2019

Удалите UITapGestureRecognizer из вашего контроллера или класса.

Измените свой пользовательский UICollectionReusableView с этим кодом: -

protocol ReviewFooterDelegate: NSObjectProtocol {
    func submitReviewDelegate(text: String, rating: Float)
    func donePicker()
    func cancelPicker()
    func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
}

class ReviewFooterCell: UICollectionReusableView {

    @IBOutlet var text: UITextView!
    @IBOutlet var submitButton: UIButton!
    @IBOutlet var rating: CosmosView!
    var reviewFooterDelegate: ReviewFooterDelegate!
    @IBOutlet var problem: UITextField!
    let pickerView = UIPickerView()
    var arr = ["1","2","3","4","5"]
    @IBAction func submitButtonPressed(_ sender: Any) {
        reviewFooterDelegate.submitReviewDelegate(text: self.text.text, rating: Float(rating.rating))
    }

    override func awakeFromNib() {
        super.awakeFromNib()
       setUpTextFieldInputView()
    }
    func setUpTextFieldInputView() {
        problem.inputView = pickerView
        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(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(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
    }
    @objc func donePicker() {
        problem.resignFirstResponder()
        reviewFooterDelegate.donePicker()
    }
    @objc func cancelPicker() {
        problem.resignFirstResponder()
        reviewFooterDelegate.cancelPicker()
    }
}
extension ReviewFooterCell : UIPickerViewDelegate ,UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

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

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

    func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
       print(arr[row])
        reviewFooterDelegate.pickerView(pickerView, didSelectRow: row, inComponent: component)
    }
}

В приведенном выше коде добавлены новые методы протокола для pickerView done и отмените действия кнопок, также добавлен метод didSelectRow Delegate в pickerView для легкого доступа.

В вашем методе viewForSupplementaryElementOfKind (Remove UITapGestureRecognizer): -

let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "ReviewFooterCell", for: indexPath) as! ReviewFooterCell
footerView.reviewFooterDelegate = self
return footerView
...