Swift 3.1 UITableViewController作为子视图或弹出窗口

时间:2017-06-01 14:01:27

标签: ios uitableview uiviewcontroller swift3

我有一项棘手的任务。我有TableUIViewController(父UIViewController),有两个tableViews,按钮等。这个UIViewController显示有关咖啡馆中的表的信息。

我还有另一个名为MenuTableViewController的控制器(父级是UITableViewController),这是一个显示菜单项列表的独立视图。只有三个UI项目 - 每个单元格中有两个标签和按钮。

思想: 我想以两种不同的方式使用这个MenuTableViewController。

  1. 如果从主菜单执行此视图的segue - 只显示菜单并允许用户编辑每个单元格。 Button.title =“打开”。

  2. 如果从TableUIViewController打开了视图 - 将按钮标题更改为“选择”,如果按下按钮创建订单等,则返回MenuTableViewController。

  3. 我发现执行segue +为segue做准备对我有用,但如果我使用segue,我遇到了导航控制器的问题 - 我完全失去了“后退”按钮,无法返回主菜单。

    所以我认为我可以使用AddSubView或一些弹出窗口执行以下步骤:

    1. 单击TableUIViewController中的按钮

    2. 显示MenuTableViewController

    3. 点击某个按钮

    4. 返回TableUIViewController - 理想情况下没有任何重新初始化,以保留所有变量的值。

    5. 但我无法理解如何在这里使用AddSubview。有人可以指导我一下吗?或者提供一些例子。在这里找不到任何好东西。

      以下是我的课程:

      TableUIViewController

      import UIKit
      import CoreData
      
      class TableUIViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, GuestAtTableTableViewCellDelegate, OrderInTableTableViewCellDelegate {
          //MARK: variables:
          //The following three variables will be set before segue to this view.
          fileprivate let myGenericFunctions = MyGenericFunctions()
          var tableName: String? = nil
          var currentTable: TablesTable? = nil
          var currentTableSession: TableSessionTable? = nil
          let tableSessionTable = TableSessionTable()
          let guestsTable = GuestsTable()
          fileprivate var countOfGuests: Int {
              get {
                  guard currentTableSession != nil else {return 0}
                  return guestsTable.getActiveGuestsForTable(tableSession: currentTableSession!)!.count
              }
          }
          fileprivate var guestsTableFetchedResultsController: NSFetchedResultsController<GuestsTable>?
          fileprivate var ordersTableFetchedResultsController: NSFetchedResultsController<OrdersTable>?
      
      
          //MARK: IBOutlets
          @IBOutlet weak var tableCapacityLabel: UILabel!
          @IBOutlet weak var tableCountOfGuestsLabel: UILabel!
          @IBOutlet weak var tableOpenTimeLabel: UILabel!
          @IBOutlet weak var tableDescriptionTextView: UITextView!
          @IBAction func closeTableButtonPressed(_ sender: UIButton) {
              guard currentTableSession != nil else {return}
              guestsTable.removeAllGuestsForTable(tableSession: currentTableSession!)
              updateGuestsTableView()
              updateOrdersTableView()
              tableSessionTable.removeTableSession(tableSession: currentTableSession!)
              currentTableSession = nil
              updateLabels()
          }
          @IBOutlet weak var guestsTableView: UITableView!
          @IBOutlet weak var ordersTableView: UITableView!
      
          @IBAction func addGuestButtonPressed(_ sender: UIButton) {
              if currentTableSession == nil {
                  currentTableSession = tableSessionTable.createTableSession(table: currentTable!)
              }
              if let capacity = Int(tableCapacityLabel.text!) {
                  guard capacity > countOfGuests else {return}
              }
      
              let guestsTable = GuestsTable()
              guestsTable.addNewGuest(tableSession: currentTableSession!)
              updateGuestsTableView()
              updateLabels()
          }
          @IBAction func addOrderButtonPressed(_ sender: UIButton) {
              guard currentTableSession != nil else {return}
      
      
      
          }
      
      
          //MARK: functions:
          override func viewDidLoad() {
              super.viewDidLoad()
              guestsTableView.dataSource = self
              guestsTableView.delegate = self
              ordersTableView.dataSource = self
              ordersTableView.delegate = self
      
              updateGuestsTableView()
              updateLabels()
          }
      
      
          private func updateLabels() {
              tableCapacityLabel.text = String(describing: currentTable!.tableCapacity)
              tableCountOfGuestsLabel.text = String(describing: countOfGuests)
              if currentTableSession != nil {
                  tableOpenTimeLabel.text = String(describing: myGenericFunctions.convertDate(inputDate: currentTableSession!.openTime!))
              } else {
                  tableOpenTimeLabel.text = " - "
              }
              if currentTable!.tableDescription != nil {
                  tableDescriptionTextView.text = currentTable!.tableDescription
              }
          }
      
          //MARK: Delegates of cell buttons
          func didPressGuestCellButton(guest: GuestsTable) {
              guestsTable.closeGuest(guest: guest)
              updateLabels()
              updateGuestsTableView()
          }
      
          func didPressOrderCellButton(order: OrdersTable) {
      
          }
      
          //MARK: Functions for tableViews update
          private func updateGuestsTableView () {
              guard currentTableSession != nil else {return}
              let tableView = guestsTableView
              let context = AppDelegate.viewContext
              let request : NSFetchRequest<GuestsTable> = GuestsTable.fetchRequest()
              request.predicate = NSPredicate(format: "table= %@", currentTableSession!)
              request.sortDescriptors = [NSSortDescriptor(key: "openTime", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
              guestsTableFetchedResultsController = NSFetchedResultsController<GuestsTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
              try? guestsTableFetchedResultsController?.performFetch()
              tableView?.reloadData()
          }
      
          private func updateOrdersTableView () {
              let tableView = ordersTableView
              let context = AppDelegate.viewContext
              let request : NSFetchRequest<OrdersTable> = OrdersTable.fetchRequest()
              request.sortDescriptors = [NSSortDescriptor(key: "menuItem", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
              ordersTableFetchedResultsController = NSFetchedResultsController<OrdersTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
              try? ordersTableFetchedResultsController?.performFetch()
              tableView?.reloadData()
          }
      
          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              if tableView == self.guestsTableView {
                  let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestAtTableTableViewCell
                  if let guest = guestsTableFetchedResultsController?.object(at: indexPath) {
                      cell.guestNameLabel.text = guest.guestName
                      cell.openTimeLabel.text = "Пришел: " + myGenericFunctions.convertDate(inputDate: guest.openTime!)
                      if let closeTime = guest.closeTime {
                          cell.closeTimeLabel.text = "Ушел: " + myGenericFunctions.convertDate(inputDate: closeTime)
                          cell.closeGuestButton.isEnabled = false
                          cell.guestNameLabel.textColor = UIColor.darkGray
                          cell.openTimeLabel.textColor = UIColor.darkGray
                          cell.closeTimeLabel.textColor = UIColor.darkGray
                      }
                      cell.cellDelegate = self
                      cell.guest = guest
                  }
                  return cell
              }
              else {
                  let cell = tableView.dequeueReusableCell(withIdentifier: "orderCell", for: indexPath)
                  return cell
              }
          }
      
          func numberOfSections(in tableView: UITableView) -> Int {
              if tableView == self.guestsTableView {
                  return guestsTableFetchedResultsController?.sections?.count ?? 1
              }
              else if tableView == self.ordersTableView {
                  return ordersTableFetchedResultsController?.sections?.count ?? 1
              }
              else {return 1}
          }
      
          func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
              if tableView == self.guestsTableView {
                  if let sections = guestsTableFetchedResultsController?.sections, sections.count > 0 {
                      return sections[section].numberOfObjects
                  }
                  else {
                      return 0
                  }
              }
              else if tableView == self.ordersTableView {
                  if let sections = ordersTableFetchedResultsController?.sections, sections.count > 0 {
                      return sections[section].numberOfObjects
                  }
                  else {
                      return 0
                  }
              }
              else {return 0}
          }
      
          func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
              if tableView == self.guestsTableView {
                  if let sections = guestsTableFetchedResultsController?.sections, sections.count > 0 {
                      return sections[section].name
                  }
                  else {
                      return nil
                  }
              }
              else if tableView == self.ordersTableView {
                  if let sections = ordersTableFetchedResultsController?.sections, sections.count > 0 {
                      return sections[section].name
                  }
                  else {
                      return nil
                  }
              }
              else {return nil}
      
          }
      
          func sectionIndexTitles(for tableView: UITableView) -> [String]? {
              if tableView == guestsTableView {
                  return guestsTableFetchedResultsController?.sectionIndexTitles
              }
              else {
                  return ordersTableFetchedResultsController?.sectionIndexTitles
              }
          }
      
          func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
              if tableView == guestsTableView {
                  return guestsTableFetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
              }
              else if tableView == ordersTableView {
                  return ordersTableFetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
              }
              else {return 0}
          }
      
          //Prepare for segues
          /*override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
              if segue.identifier == "openMenuToAddOrder" {
                  if let menuTVC = segue.destination as? MenuTableViewController {
                      menuTVC.isOpenedFromTable = true
                      menuTVC.currentTableSession = currentTableSession
                      menuTVC.currentTable = currentTable
                  }
              }
          }*/
      }
      

      ManuTableViewController:

      class MenuTableViewController: FetchedResultsTableViewController, MenuTableViewCellDelegate {
          var tableName: String? = nil
          var currentTable: TablesTable? = nil
          var currentTableSession: TableSessionTable? = nil
          var isOpenedFromTable: Bool = false
          let ordersTable = OrdersTable()
          fileprivate var fetchedResultsController: NSFetchedResultsController<MenuTable>?
      
          override func viewDidLoad() {
              updateMenuTableView()
              self.navigationItem.rightBarButtonItem = self.editButtonItem
          }
      
          //MARK: delegate of table cell
          func didPressMenuItemCellButton (menuItem: MenuTable) {
              if isOpenedFromTable {
                  ordersTable.addOrUpdateOrderForTableSession(tableSession: currentTableSession!, menuItem: menuItem)
                  performSegue(withIdentifier: "returnToTableView", sender: self)
              } else {
                  //here will be code for editing menu item
              }
          }
      
          //MARK: Functioms for table view update
          private func updateMenuTableView () {
              let context = AppDelegate.viewContext
              let request : NSFetchRequest<MenuTable> = MenuTable.fetchRequest()
              request.sortDescriptors = [NSSortDescriptor(key: "itemName", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))]
              fetchedResultsController = NSFetchedResultsController<MenuTable>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
              fetchedResultsController?.delegate = self
              try? fetchedResultsController?.performFetch()
              tableView.reloadData()
          }
      
          override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              let cell = tableView.dequeueReusableCell(withIdentifier: "menuCell", for: indexPath) as! MenuTableViewCell
              if let menuTable = fetchedResultsController?.object(at: indexPath) {
                  cell.menuItemNameLabel.text = menuTable.itemName
                  cell.menuItemDescriptionLabel.text = menuTable.itemDescription
                  cell.menuItemPriceLabel.text = String(describing: menuTable.itemPrice)
                  if isOpenedFromTable == true {
                      cell.button.setTitle("Выбрать", for: UIControlState.normal)
                  } else {
                      cell.button.setTitle("Открыть", for: UIControlState.normal)
                  }
                  cell.menuItem = menuTable
                  cell.cellDelegate = self
              }
              return cell
          }
          //Prepare for segues
          override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
              if segue.identifier == "returnToTableView" {
                  if let tableTVC = segue.destination as? TableUIViewController {
                      tableTVC.currentTableSession = currentTableSession
                      tableTVC.currentTable = currentTable
                      tableTVC.tableName = currentTable?.tableName
                  }
              }
          }
      }
      
      extension MenuTableViewController {
          override func numberOfSections(in tableView: UITableView) -> Int {
              return fetchedResultsController?.sections?.count ?? 1
          }
      
          override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
              if let sections = fetchedResultsController?.sections, sections.count > 0 {
                  return sections[section].numberOfObjects
              }
              else {
                  return 0
              }
          }
      
          override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
              if let sections = fetchedResultsController?.sections, sections.count > 0 {
                  return sections[section].name
              }
              else {
                  return nil
              }
          }
      
          override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
              return fetchedResultsController?.sectionIndexTitles
          }
      
          override func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
              return fetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
          }
      }
      

      更新 这是我的故事板。我有一种感觉,我没有正确使用导航控制器。但是在视图之间没有一些控制器 - 后退按钮不会出现。对不起图像中的俄文。 enter image description here

      标记为已解决后更新:

      我已删除performSegue并将来自Controller的segue置于按钮本身。现在导航控制器保持应该按下后退按钮。 还将Update UI函数移动到viewWillAppear以在segues之后保持表更新。

      override func viewWillAppear(_ animated: Bool) {
          updateGuestsTableView()
          updateOrdersTableView()
          updateLabels()
          updateOrdersTableView()
      }
      

      另一个更新,现在它完全按照我的意愿工作。 我添加了一个由Menu Cell Button调用的函数,以返回到之前的ViewController(与Back按钮相同):

          //MARK: delegate of table cell
          func didPressMenuItemCellButton (menuItem: MenuTable) {
              if isOpenedFromTable {
                  ordersTable.addOrUpdateOrderForTableSession(tableSession: currentTableSession!, 
      
      menuItem: menuItem)
                  _ = navigationController?.popViewController(animated: true)
              } else {
                  //here will be code for editing menu item
              }
          }
      

1 个答案:

答案 0 :(得分:1)

听起来你想要一个像这样的结构:

enter image description here

如果从主菜单中选择“编辑食物菜单”,您将直接进入“食物菜单”。如果您选择“接单”,您将看到“表格列表”。

如果您选择了“编辑食物菜单”,那么您的食物菜单代码应显示“编辑”作为表格中每行的按钮标题。点击“编辑”将转到“编辑菜单项”视图。

如果您选择了“接单”,然后从列表中选择一个表格,那么会带您进入“食物菜单”,但在这种情况下,您的食物菜单代码应显示“订单” “作为按钮标题。点击“订单”会将食品添加到您的数据结构中,或者显示确认警报,或者执行此时需要的任何其他操作。

由于所有视图都是同一个导航控制器结构的一部分,因此您可以通过选择导航栏上的标准“&lt; Back”按钮来“向上移动堆栈”。

希望有道理:)