Swift 4 - проблемы с делегатом, UITextField возвращает ноль - PullRequest
0 голосов
/ 08 января 2019

Мне нужна помощь с моим кодом. У меня есть UITextField в UICollectionViewCell. И я хочу получить доступ к данным моего UICollectionViewController. Возвращаемое значение nil.

Я использую метод делегата для передачи данных между классами, но мое значение возвращает nil. Я не вижу, где проблема? Надеюсь, вы, ребята, можете мне помочь. Спасибо!

import UIKit
import Firebase


class EditUserProfileController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UIGestureRecognizerDelegate {

weak var editUserProfileCellDelegate: EditUserProfileCell?

let cellId = "cellId"
    super.viewDidLoad()

    setupSaveButton()


    setupNavigationBar()

    collectionView?.register(EditUserProfileCell.self, forCellWithReuseIdentifier: cellId)


}


fileprivate func setupSaveButton() {
    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(handleUpdateProfile))

}

    @objc func handleUpdateProfile() {


        editUserProfileCellDelegate?.delegate = self

        guard let name = editUserProfileCellDelegate?.nameTextfield.text, name.count > 0 else { return }
        guard let username = editUserProfileCellDelegate?.usernameTextfield.text, username.count > 0 else { return }
        guard let email = editUserProfileCellDelegate?.emailTextfield.text, username.count > 0 else { return }

        guard let city = editUserProfileCellDelegate?.cityTextfield.text else { return }
        guard let country = editUserProfileCellDelegate?.countryTextfield.text else { return }

        guard let fcmToken = Messaging.messaging().fcmToken else { return }

        guard let uid = Auth.auth().currentUser?.uid else { return }

        let ref = Database.database().reference().child("users")

        let disctionaryValues = ["username": username, "name": name, "email": email, "city": city, "country": country,"fcmToken": fcmToken]

        let values = [uid: disctionaryValues]

        ref.setValue(values) { (err, ref) in
            if let err = err {
                print("Failed to update user:", err)
                return
            }

            print("Succesfully updated user: ", self.user?.username ?? "")

        }

    }

И мой UITextField:

import UIKit
import Firebase


class EditUserProfileCell: UICollectionViewCell, 
UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    let nameTextfield: UITextField = {
    let tf = UITextField()

    let attributedText = NSMutableAttributedString(string: "Name", 
    attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor.black])

    tf.attributedPlaceholder = attributedText

    tf.textColor = UIColor.black
    tf.font = UIFont.systemFont(ofSize: 14)
    tf.borderStyle = .none
    tf.layer.backgroundColor = UIColor.white.cgColor
    tf.layer.masksToBounds = false
    tf.layer.shadowColor = UIColor.lightGray.cgColor
    tf.layer.shadowOffset = CGSize(width: 0.0, height: 0.5)
    tf.layer.shadowOpacity = 1.0
    tf.layer.shadowRadius = 0.0

    return tf

}()

Я ожидаю, что вернет ввод в моем текстовом поле, например, имя. Но теперь я могу получить только nil.

1 Ответ

0 голосов
/ 08 января 2019

Похоже, вы немного сбиты с толку, как работают делегаты. Итак, я создал пример:

protocol Delegate: class { // declare delegate protocol
    func someFunction()
}

class Cell: UICollectionViewCell {

    weak var delegate: Delegate? // declare delegate variable

    func callDelegate() {
        delegate?.someFuntion() // call method on delegate
    }
}

class ViewController: UICollectionViewController {
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        ...
        cell.delegate = self // set delegate of cell as your view controller
        ...
    }
}

extension ViewController: Delegate { // implement protocol
    func someFunction() { // this method gets called when you call this method on delegate from some cell
    }
}

Хорошо, это должно дать вам лучшее представление об этой проблеме. Итак, теперь давайте преобразуем его в ваш код.

Начать с объявления протокола

protocol EditUserProfileCellDelegate: class {
    func nameSaved(_ name: String)
}

теперь создайте переменную в подклассе ячейки и вызовите делегат, когда текстовое поле закончило редактирование

class EditUserProfileCell: UICollectionViewCell, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

    weak var delegate: EditUserProfileCellDelegate?
    ...
}

extension EditUserProfileCell: UITextFieldDelegate {
    func textFieldDidEndEditing(_ textField: UITextField) {
        if textField == nameTextField {
            delegate?.nameSaved(textField.text!)
        }
    }
}

теперь давайте реализуем протокол для вашего контроллера представления

extension EditUserProfileController: EditUserProfileCellDelegate {
    func nameSaved(_ name: String) {
        ... // do something with name
    }
}

и, наконец, не забудьте установить делегат вашей ячейки в cellForItemAt

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    ...
    cell.delegate = self
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...