我想将带有所有用户信息的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)
}
}
答案 0 :(得分:2)
如果您需要将数据从一个ViewController传递到另一个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!
}
}
答案 1 :(得分:2)
2件事: 首先,如果您只想将数据从一个viewController传递到另一个viewController,则不需要使用委托模式,只需在prepare表单segue上将对象传递给下一个viewController。
第二,如果要实现委托模式,则应该有一个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
}
}
}
答案 2 :(得分:1)
要将UserModel对象从ShowUserViewController
传递到ChatViewController
,应使用名为Dependency Injection
的东西:
因此,您将在ShowUserViewController
内执行以下操作:
@IBAction func chatButtonTapped(_ sender: UIBarButtonItem) {
performSegue(withIdentifier: "UserInfoToChatVC", sender: nil)
}
注意:sender参数应该是发起segue的对象。它可能是自我的,即ShowUserViewController
对象,但是我建议不要传递UserModel
对象,因为该对象不会启动Segue,并且与导航完全无关。稍后应将其注入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
}