我基本上试图重新创建whatsapp。我的MainVC有一个TableView,它显示所有当前的对话,并且有一个推送到ChatVC的segue以显示整个对话。
当用户想要开始新对话时,他们点击右上角的按钮,UserListVC来自底部并显示用户列表。
我的想法是,当用户点击用户时," UsersListVC"解散(显示mainVC)并调用一个函数来打开ChatVC。但是,在MainVC的这个dimiss之后,我还没能成功调用函数。
请不要现在我没有推送任何数据我只想让segue正常工作
MainVC.swift
func showChatVC() {
print("FUnction called")
let showChat = ChatVC()
navigationController?.pushViewController(showChat, animated: false)
}
UsersListVC.swift
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
dismiss(animated: true) {
MainVC().showChatVC()
}
}
我尝试了一些不同的变化,我似乎无法在MainVC中调用该函数。我是不是太顽固,我的想法是这样做的?我应该从UsersListVC直接segue到ChatVC
答案 0 :(得分:1)
尝试以下代码
步骤1
设置故事板标识符。
然后尝试以下代码
<强> MainVC.swift 强>
func showChatVC() {
let showChat = self.storyboard!.instantiateViewControllerWithIdentifier("ChatVc_ID") as! ChatVC
self.navigationController?.pushViewController(showChat, animated: false)
}
<强> UsersListVC.swift 强>
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
dismiss(animated: true) {
let mainVC = self.storyboard!.instantiateViewControllerWithIdentifier("MainVC_ID") as! MainVC
mainVC.showChatVC()
}
}
答案 1 :(得分:1)
这里有很多答案,我想我应该使用委托模式为这些类型的问题添加解决方案。
使用委托,您可以从UsersListVC调用MainVC中的函数,这样可以更容易地切换到ChatVC,并且在将所选用户传递给ChatVC时也会有所帮助。
制作委托模式:
创建一个协议,指定你的委托类必须实现的功能,通常我在委托类上面这样做,所以MainVC。
protocol UsersListDelegate: class {
func newConversationCreated(withUser user: AnyObject)
}
让您的委托类(MainVC)符合协议并实现所需的功能
class MainVC: UIViewController, UsersListDelegate {
func newConversationCreated(withUser user: AnyObject) {
//I'll fill this in later in my answer
}
}
在UsersListVC中创建一个变量来保存
中的委托类class UsersListVC: UIViewController {
weak var delegate: UsersListDelegate!
}
当您从MainVC呈现UsersList时,将委托变量设置为MainVC(self),例如,如果您转到UsersList,则可以在准备segue时完成此操作。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? UsersListVC {
destination.delegate = self
}
}
或者如果你没有segue提出它:
func presentUsersList() {
let userListsVC = UsersListVC()
userListsVC.delegate = self
self.present(userListsVC, animated: true)
}
您的委托模式现已完成。要在创建新会话并关闭UserListsVC时调用委托功能,您可以这样做
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
delegate.newConversationCreated(withUser: /*Your User Object*/)
}
在MainVC中,您可以将newConversationCreated函数实现为:
e.g。
func newConversationCreated(withUser user: AnyObject) {
dismiss(animated: true) {
let showChat = ChatVC()
showChat.user = user
navigationController?.pushViewController(showChat, animated: false)
}
}
P.S。从MainVC调用dismiss可能看起来很奇怪,但这实际上是根据apple的最佳实践(参见question中的答案为什么)。它会解雇用户列表,不用担心。
答案 2 :(得分:0)
尝试从您的tableView's didSelectRow
方法发送操作,例如
UIApplication.sharedApplication().sendAction("showChatVC", to: nil, from: nil, forEvent: nil)
希望这会有所帮助。
答案 3 :(得分:0)
我建议使用NotificationCenter
:
在MainVC
注册NewChatCreateNotification
,例如:
NotificationCenter.default.addObserver(self, selector: #selector(autoNavigateToNewChat(_:)), name: NSNotification.Name(rawValue: "NewChatCreateNotification"), object: nil)
仍在MainVC
,在autoNavigateToNewChat:
方法中,推ChatVC
然后在您解除UsersListVC
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Use this dict to populate the userInfo of the notification, then you can use it when you push to ChatVC.
//You can obviously add more info to it like userId etc. as long as the data conforms to: [AnyHashable: Any]
let dict = ["chatId" as NSString : <the selected chatId> as NSNumber]
dismiss(animated: true) {
NotificationCenter.default.post(name: Notification.Name(rawValue: "NewChatCreatedNotification"), object: self, userInfo: dict as [AnyHashable: Any])
}
}
答案 4 :(得分:0)
以下内容适用于您的故事板设置。确保在故事板中设置segue标识符。我在UsersListVC
。
import Foundation
import UIKit
internal enum SegueIdentifier: String {
case showChat = "showChat"
case showUserList = "showUserList"
}
internal final class MainVC: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == SegueIdentifier.showUserList.rawValue, let vc = segue.destination as? UsersListVC {
vc.completion = {
[weak self] in self?.performSegue(withIdentifier: SegueIdentifier.showChat.rawValue, sender: nil)
}
}
}
}
internal final class ChatVC: UIViewController {
}
internal final class UsersListVC: UIViewController {
internal var completion: (() -> ())? = nil
@IBAction func close(_ sender: UIButton) {
dismiss(animated: true) {
[weak self] in self?.completion?()
}
}
}
答案 5 :(得分:0)
如果我没有弄错,你可以在解雇关闭中创建一个MainVC
的新实例。
dismiss(animated: true) {
MainVC().showChatVC()
}
由于这个新的ViewController从未在屏幕上显示,因此它也无法显示另一个ViewController。
尝试获取对现有MainVC
的引用。
dismiss(animated: true) { [weak self] in
if let mainVC = self?.presentingViewController as? MainVC {
self?.mainVC.showChatVC()
}
}
否则请尝试使用通知方法。