как отправить информацию из tableViewController, встроенного в ViewController, в этот контроллер представления? - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть контроллер представления, и внутри этого контроллера представления у меня есть контроллер представления таблицы (см. Изображение здесь) .

Программа работает следующим образом:

Пользователь набирает кому-то адрес электронной почты, представление таблицы обновляется по мере того, как пользователь печатает.

Когда пользователь уверен, что в таблице отображается нужная ему ячейка, он может щелкнуть по ней, и информация из нажатой ячейки "автозаполнит" то, что набрал пользователь.

У меня естьоба вида контроллеров (табличный и обычный).Я знаю, как отправить информацию из viewController в tableViewController, но я не знаю, как это изменить.Прикрепленный код для viewController:

class PayViewController: UIViewController, STPAddCardViewControllerDelegate {


    var finalAmmount = ""
    var toPay = 0.00
    var successfullPayment = false
    var payToUser = ""
    var updatedBalance = ""

    lazy var functions = Functions.functions()
    var resultText = "" // empty
    var input = ""
    var email = ""

    var sele = ""

    @IBOutlet weak var forField: UITextField!
    @IBOutlet weak var toField: UITextField!
    @IBOutlet weak var ammountLabel: UILabel!

    //toField.addTarget(self, action: #selector(UsersTableViewController.textChanges(_:)), for: UIControl.Event.editingChanged)
    var myTable:UsersTableViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
        //var myTable:UsersTableViewController?
        ammountLabel.text = "$ \(finalAmmount)"
        myTable = self.children[0] as! UsersTableViewController
        self.toField.addTarget(myTable, action: #selector(UsersTableViewController.textChanges(_:)), for: UIControl.Event.editingChanged)
    }


    @IBAction func paraFieldEdditingStarted(_ sender: Any) {
         myTable!.filterContent(searchText:forField.text!)
        //self.toField.addTarget(, action: #selector(UsersTableViewController.textChanges(_:)), for: UIControl.Event.editingChanged)
    }

и следующий код для tableViewController

class UsersTableViewController: UITableViewController, UISearchResultsUpdating {

    func updateSearchResults(for searchController: UISearchController) {
        //update the search results
        filterContent(searchText: searchT)
    }


    @objc func textChanges(_ textField: UITextField) {
        let text = textField.text! // your desired text here
        // Now do whatever you want.
        searchT = text
        filterContent(searchText:textField.text!)
    }


    @IBOutlet var usersTableView: UITableView!
    let searchController = UISearchController(searchResultsController: nil)

    var searchT = ""
    var usersArray = [NSDictionary?]()
    var filteredUsers = [NSDictionary?]()

    var databaseRef: DatabaseReference!


    override func viewDidLoad() {
        super.viewDidLoad()

        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true

        tableView.tableHeaderView = searchController.searchBar

        databaseRef = Database.database().reference()
        let usersRef = databaseRef.child("users")
        let query = usersRef.queryOrdered(byChild: "email")
        query.observe(.childAdded, with: {(snapshot) in
            self.usersArray.append((snapshot.value as? NSDictionary?)!)

            //insert the rows
            self.usersTableView.insertRows(at: [IndexPath(row:self.usersArray.count-1, section: 0)], with: UITableView.RowAnimation.automatic)


        }) { (error) in
            print(error.localizedDescription)
        }

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows

        if (self.searchT != ""){
            return filteredUsers.count
        }
        return self.usersArray.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        let user: NSDictionary
        if ((searchT != "")){
            user = filteredUsers[indexPath.row]!
        }else{
            user = self.usersArray[indexPath.row]!
        }

        cell.textLabel?.text = user["email"] as? String
        cell.detailTextLabel?.text = user["name"] as? String

        return cell
    }

    func filterContent(searchText: String){

        self.filteredUsers =  self.usersArray.filter({ user in
            let userEmail = user!["email"] as? String
            return(userEmail?.lowercased().contains(searchText.lowercased()))!
        })

        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //let vc = storyboard?.instantiateViewController(withIdentifier: "ConfirmationVC") as? PayViewController
        //vc?.forField.text = filteredUsers[indexPath.row]!["email"] as! String
    }

    func setContents(searchText: String){
       // searchT = searchText
    }

, как вы можете видеть в самом конце tableviewcontroller, я пыталсяотправить информацию обратно с помощью vc.Есть ли более простой способ сделать это?

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

Хотя создание протокола делегата и добавление свойства делегата в ваш tableViewController - это хороший способ, есть и другой путь.

Просто добавьте свойство к вашему tableViewController, которое является закрытием:

var updatedData: ((_ email: String, _ name: String)->Void)?

Ваш tableViewController может отправлять информацию «вверх по цепочке» неизвестному родительскому контроллеру представления, просто вызывая

self.updatedData?(theEmail, theName)

В viewDidLoad вашего родительского контроллера представления (или где бы вы ни выбрали), сделайте так:

tableViewController.updatedData = 
  { [weak self] email, name in
      // do your code here
  }

Так просто.У этого подхода есть свои плюсы и минусы, а не формальный протокол.Я настоятельно рекомендую вам попробовать оба подхода и познакомиться с обоими, чтобы со временем вы узнали, когда использовать какой подход.Этот подход неформален и часто более удобен для передачи «по цепочке» в приложении (по сравнению с SDK), особенно если родительский контроллер представления вряд ли будет заменен другим.Но также вполне разумно сказать, что вы всегда хотите формализовать все через протоколы.Просто немного больше кода таким образом.

Я действительно часто использую этот неформальный подход.Я также обертываю кучу этих переменных замыкания в протокол, который будет реализовывать моя модель представления, просто для того, чтобы я мог внедрить зависимости в другую модель представления, когда я тестирую пользовательский интерфейс одного контроллера представления независимо от моего приложения.Во всяком случае, это другая ситуация (viewModel для связи с viewController, а не ситуация от дочернего viewController до родительского соединения viewController).

0 голосов
/ 09 февраля 2019

Ваша попытка

let vc = storyboard?.instantiateViewController(withIdentifier: "ConfirmationVC") as? PayViewController

... не удалась, поскольку она создает новый, новый экземпляр PayViewController, а не экземпляр, содержащий этот UsersTableViewController.

PayViewController - это parent этого UsersTableViewController.Вам может потребоваться привести его к PayViewController, чтобы вызвать метод или установить свойство в нем:

let vc = self.parent as? PayViewController

(Обратите внимание, что для одного контроллера представления является необычным устанавливать интерфейс другого контроллера представления непосредственно каквы пытаетесь это сделать. Вы должны предоставить PayViewController метод, который UsersTableViewController может вызывать в хорошем порядке.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...