我的表视图单元格显示一个带有两个不同按钮元素的实体。我希望能够启动一个视图控制器,如果我单击第一个按钮和另一个视图控制器,则在我单击第二个按钮时会显示饮料的选择,该视图控制器会显示出食物的选择。
我能够正确地将数据传递给新的视图控制器,但似乎无法忽略当前视图并加载新的视图。我的代码是这样:
在表查看单元格中
@IBAction func foodBtnPressed(_ sender: Any) {
print("foodBtn pressed")
print("customer is (customer?.name)")
vc.loadChooserScreen(toChoose: "Food", forCustomer: customer!)
}
@IBAction func beverageBtnPressed(_ sender: UIButton) {
print("beverageBtn pressed")
print("customer is (customer?.name)")
vc.loadChooserScreen(toChoose: "Beverage", forCustomer: customer!)
}
在表查看控制器中
func loadChooserScreen(toChoose: String, forCustomer: Customer) {
print("Choose (toChoose)")
print("For (forCustomer.name)")
if toChoose == "Food" {
let foodVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "foodMenu") as? FoodVC
foodVC?.loadCustomerToEdit(customer: forCustomer)
dismissVC(sender: Any.self)
}
else if toChoose == "Beverage" {
let beverageVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "beverageMenu") as? BeverageVC
beverageVC?.loadCustomerToEdit(customer: forCustomer)
dismissVC(sender: Any.self)
}
else {
// do nothing
}
}
func dismissVC(sender: Any) {
print("Reached dismissVC function in selectionMenu")
dismiss(animated: true, completion: {
self.delegate!.dismissViewController()
})
}
在此视图控制器中,我也有以下协议
protocol OrderVCProtocol {
func dismissViewController()
}
已定义
var delegate: OrderVCProtocol!
在我的根视图控制器中
func dismissViewController() {
print("Reached dismissViewController function in rootView")
if let foodVC = self.storyboard?.instantiateViewController(withIdentifier: "foodMenu") {
self.present(foodVC, animated: true, completion: nil)
}
if let beverageVC = self.storyboard?.instantiateViewController(withIdentifier: "beverageMenu") {
self.present(beverageVC, animated: true, completion: nil)
}
}
,当表视图控制器在此处称为
时,将设置委托 @IBAction func loadOrderView(_ sender: Any) {
let orderVC = self.storyboard?.instantiateViewController(withIdentifier: "orderView") as! OrderVC
orderVC.delegate = self
self.present(orderVC, animated: true, completion: nil)
}
在我的目标视图控制器中,我有以下功能
func loadCustomerToEdit(customer: Customer) {
self.customerToEdit = customer
print("IN FoodVC THE CUSTOMER TO EDIT IS (self.customerToEdit.name)")
}
和饮料中的一个相应的。
运行应用程序时,没有错误的错误,我从打印语句中从控制台中获得以下示例输出:
foodbtn按
客户是可选的("约翰")
选择食物
可选(" John")
在foodvc中,要编辑的客户是可选的("约翰")
在selectionMenu中达到了解散功能
单击饮料按钮,请进行相应的响应。
那么什么也没有发生。因此,我知道数据正确传递给了新的视图控制器,但我不知道如何解开当前屏幕并显示出选择的新屏幕。
我希望我的问题足够清楚吗?我不确定怎么了,但是控制台输出清楚地表明,该代码在试图丢弃当前视图之前运行正常。
。编辑以添加:
如果我在TableView Controller中修改了我的divivevc函数:
func dismissVC(sender: Any) {
print("Reached dismissVC function in selectionMenu")
delegate.dismissViewController()
}
控制台视图现在抛出
致命错误:未包装可选值
时出乎意料地发现了无效
,如果我再次将其修改为以下内容,则它可以返回没有错误并陷入同一位置(即打印"卡住的位置拒绝视图"的行),表明委托仍然是零..。
func dismissVC(sender: Any) {
print("Reached dismissVC function in selectionMenu")
if delegate != nil {
delegate?.dismissViewController()
} else {
print("Stuck where delegate dismisses view")
}
我通过通过通知中心和代表实施通知来解决了我的问题。首先,在我的AppDelegate文件中,我在底部添加了此行
let notifyCnt = NotificationCenter.default
接下来,我修改了我的tableview单元格函数
@IBAction func foodBtnPressed(_ sender: Any) {
notifyCnt.post(name: NSNotification.Name(rawValue: "toChoose"), object: nil, userInfo: ["toChoose": "Food", "forCustomer": customer])
}
@IBAction func beverageBtnPressed(_ sender: UIButton) {
notifyCnt.post(name: NSNotification.Name(rawValue: "toChoose"), object: nil, userInfo: ["toChoose": "Beverage", "forCustomer": customer])
}
然后,在桌面控制器中,我对此进行了修改:
protocol ChooserViewDelegate: class {
func loadChooserView(choice: String, forCustomer: Customer)
}
和定义
weak var delegate: ChooserViewDelegate?
并将其添加到我的ViewDidload部分
notifyCnt.addObserver(forName: Notification.Name(rawValue: "toChoose"), object: nil, queue: nil, using: loadChooserScreen)
最终像这样修改了我的选择器功能:
func loadChooserScreen(notification: Notification) {
guard let userInfo = notification.userInfo,
let toChoose = userInfo["toChoose"] as? String,
let planToEdit = userInfo["customer"] as? Customer else {
print("No userInfo found in notification")
return
}
delegate?.loadChooserView(choice: toChoose, forCustomer: customer)
}
然后在我的根视图控制器中,我有以下内容来替换我之前的内容:
/*Conform to ChooserViewDelegate Protocol */
func loadChooserView(choice: String, forCustomer: Customer) {
self.customer = forCustomer
dismiss(animated: false, completion: {
if choice == "Food" {
self.performSegue(withIdentifier: "food", sender: self.customer)
}
if choice == "Beverage" {
self.performSegue(withIdentifier: "beverage", sender: self.customer)
}
})
}
我通过Preparforsegue发送数据:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "food" {
if let foodVC = segue.destination as? FoodVC {
storyboard?.instantiateViewController(withIdentifier: "food")
foodVC.customerToEdit = self.customerToEdit
foodVC.delegate = self
}
}
if segue.identifier == "beverage" {
if let beverageVC = segue.destination as? BeverageVC {
storyboard?.instantiateViewController(withIdentifier: "beverage")
beverageVC.customerToEdit = self.customerToEdit
beverageVC.delegate = self
}
}
}
所以现在所有内容都可以正确加载和视图:)