2016-12-17 3 views
1

テーブルビューセルには、2つの異なるボタン要素を持つエンティティが表示されます。私は最初のボタンをクリックすると食品の選択肢を表示するView Controllerを起動でき、2番目のボタンをクリックすると、選択した飲み物を表示する別のView Controllerを起動できるようにしたい。テーブルビューの異なる要素をクリックして別の新しいビューコントローラを開くセル - Swift 3

データを新しいビューコントローラに正しく渡すことはできますが、現在のビューを閉じて新しいビューコントローラを読み込むことはできません。私のコードは次のようである:私はまた、以下のプロトコルを有し、このビューコントローラのテーブルビューコントローラ

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() 
    }) 
} 

のテーブルビューセル

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

protocol OrderVCProtocol { 
func dismissViewController() 
} 

と定義済み

私のルートビューコントローラ

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

var delegate: OrderVCProtocol! 

とテーブルビューコントローラは、私のターゲットビューコントローラ内でここ

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

およびそれに対応するBeverageVC。

私はアプリを実行すると、エラーがスローされないと、私は私のprint文からコンソールに次のサンプル出力を取得しています

foodBtn pressed

customer is Optional("John")

Choose Food

For Optional("John")

IN FoodVC THE CUSTOMER TO EDIT IS Optional("John")

Reached dismissVC function in selectionMenu

と対応する応答飲料ボタンがクリックされた場合。

何も起こりません。だから私は、データが正しく新しいビューコントローラに渡されていることを知っているが、私は現在の画面を却下し、新しいものを選択肢と共に表示する方法を知らない。

私の質問は十分に願っていますか?私は何が間違っているのかは分かりませんが、コンソール出力は、現在のビューを閉じるまでコードが正常に動作することを明確に示しています。

追加するEDITED:

を、私はこのように私のテーブルビューコントローラに私のdismissVC機能を変更する場合:

func dismissVC(sender: Any) { 
print("Reached dismissVC function in selectionMenu") 
delegate.dismissViewController() 
} 

コンソールビューは、現在

fatal error: unexpectedly found nil while unwrapping an Optional value

そして私は再びそれを変更した場合にスローされます次のように、エラーをスローして同じ場所に詰まった状態に戻ります(つまり、「デリゲートがビューを閉じる場所でスタックする」という行を表示します)。デリゲートがまだnilであることを示しています...しかし、私はそれをルートビューで設定し、このビューにロードすると、なぜそれは無用ですか?

func dismissVC(sender: Any) { 
print("Reached dismissVC function in selectionMenu") 
if delegate != nil { 
    delegate?.dismissViewController() 
    } else { 
print("Stuck where delegate dismisses view") 
} 
+0

ルートビューコントローラに 'self.storyboard' nilはありますか? – pbasdf

+0

コンソール出力の最後の行を転記するときに間違いを犯しましたが、今修正しました。コード実行は実際にはルートビューコントローラに実際には達しません。なぜ私は考えていない。 – tolkienfan2

+0

'delegate'のようなサウンドはnilです - あなたのルートビューのコントローラーでそれを設定しますか? – pbasdf

答えて

0

通知センターと代理人による通知を実装することで、私の問題を解決しました。まず、私のAppDelegateファイルに私はこれにそれを修飾テーブルビューコントローラに、そしてこの

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

に自分のテーブルビューの細胞機能を修飾、底

let notifyCnt = NotificationCenter.default 

次のページに次の行を追加:

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

と私はprepareForSegueを介してデータを介して送信:

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

これですべてが正しく読み込まれ、表示されます:)

関連する問題