通过单击表视图单元格中的不同元素 - Swift 3打开不同的新视图控制器



我的表视图单元格显示一个带有两个不同按钮元素的实体。我希望能够启动一个视图控制器,如果我单击第一个按钮和另一个视图控制器,则在我单击第二个按钮时会显示饮料的选择,该视图控制器会显示出食物的选择。

我能够正确地将数据传递给新的视图控制器,但似乎无法忽略当前视图并加载新的视图。我的代码是这样:

在表查看单元格中

    @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
        }
    }
}

所以现在所有内容都可以正确加载和视图:)

最新更新