Как установить делегата в Swift - PullRequest
0 голосов
/ 09 декабря 2018

Я хочу отправить свою UserModel со всей пользовательской информацией из ViewController (ShowUserViewController) в другой ViewController (ChatViewController) с delegate, но он не работает.

В моем ShowUserViewControllers user есть вся информация, которую я хочу отправить в ChatViewController.

var user: UserModel?

В моем ChatViewController у меня есть следующая декларация, куда я хочу отправить свои данные:

var currentUser: UserModel?

Вот мой протокол:

    protocol UserInfoToChatID {
    func observeUserID(user: UserModel)
}

Здесь я готовлю переход и устанавливаю delegate, нажимая кнопку:

} else if segue.identifier == "UserInfoToChatVC" {
        let chatVC = segue.destination as! ChatViewController
        chatVC.currentUser = self.user
    }
}

var delegate: UserInfoToChatID?

@IBAction func chatButtonTapped(_ sender: UIBarButtonItem) {
    delegate?.observeUserID(user: user!)
}

Наконец я вызываю delegate в моем ChatViewController:

    extension ChatViewController: UserInfoToChatID {

    func observeUserID(user: UserModel) {
        self.currentUser = user
        performSegue(withIdentifier: "UserInfoToChatVC", sender: self)
    }
}

Ответы [ 3 ]

0 голосов
/ 09 декабря 2018

2 вещи: во-первых, если вы просто хотите передать данные из одного viewController в другой viewController, вам не нужно использовать шаблон делегата, просто передайте объект следующему viewController при подготовке формы segue.

во-вторых, если вы хотите реализовать шаблон делегата, у вас должен быть один viewController, чем вызов делегата, а другой реализует функции.

пример:

protocol ExampleDelegate: class {
   func delegateFunction() 
}


class A {
   //have delegate var
   weak var delegate: ExampleDelegate?

   // someWhere in the code when needed call to the delegate function... 
   delegate?.delegateFunction()
}

Class B: ExampleDelegate {
   func delegateFunction() {
      // do some code....
   }

   //when you move to the next viewControoler(to A in that case)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "AClass" {
        if let vc = segue.destination as? A {
            vc.delegate = self
        }
    }
}
0 голосов
/ 09 декабря 2018

Чтобы передать объект UserModel вперед от ShowUserViewController до ChatViewController, вы должны использовать что-то под названием Dependency Injection:

Так что вы будете делать что-то подобное внутри ShowUserViewController:

@IBAction func chatButtonTapped(_ sender: UIBarButtonItem) {
    performSegue(withIdentifier: "UserInfoToChatVC", sender: nil)
}

Примечание. Параметр отправителя должен быть объектом, инициировавшим переход.Это может быть self, то есть объект ShowUserViewController, но я бы не советовал передавать объект UserModel, потому что этот объект не инициировал переход и не имеет никакого отношения к навигации.Это должно быть введено внутрь Destination Controller позже.

В том же файле переопределите метод prepare(for:):

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "UserInfoToChatVC" {
        let chatVC = segue.destination as! ChatViewController
        chatVC.currentUser = self.user
    }
}

Я полагаю, вы в основном выполнили эту часть правильно,но вам может потребоваться связаться с ChatViewController до ShowUserViewController.

. В этом случае вы можете и должны использовать Delegation.

Создать что-то подобное внутри ShowUserViewController:

protocol ChatViewControllerDelegate: class {
    func didUpdateUser(_ model: UserModel)
}

class ChatViewController: UIViewControler {

    var user: UserModel?

    weak var delegate: ChatViewControllerDelegate?
    /* more code */

    func someEventHappened() {
        delegate?.didUpdateUser(self.user!)
    }
}

Наконец, к методу prepare(for:) необходимо добавить дополнительную строку:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "UserInfoToChatVC" {
        let chatVC = segue.destination as! ChatViewController
        chatVC.currentUser = self.user
        // Add this line...
        chatVC.delegate = self
    }
}

И указать, что ShowUserViewController реализует протокол ChatViewControllerDelegate, затемпереопределить метод didUpdateUser(_:):

func didUpdateUser(_ model: UserModel) {
    // Some code here
}
0 голосов
/ 09 декабря 2018

Если вам нужно передать данные из одного ViewController в другой, вам не нужно использовать делегатов для этого.Вы можете просто передать эти данные в качестве параметра отправителя метода performSegue:

performSegue(withIdentifier: "UserInfoToChatVC", sender: user!)

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

    ...
    } else if segue.identifier == "UserInfoToChatVC" {
        let chatVC = segue.destination as! ChatViewController
        chatVC.currentUser = sender as! UserModel
    }
}

Но в вашем случае вам на самом деле не нужно передавать user в качестве отправителя.Вы можете просто назначить переменную назначения currentUser как глобальную переменную ShowUserViewController user

    ...
    } else if segue.identifier == "UserInfoToChatVC" {
        let chatVC = segue.destination as! ChatViewController
        chatVC.currentUser = user!
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...