菜鸟教程小白 发表于 2022-12-13 01:38:00

ios - Swift 3.1 UITableViewController 作为 subview 或弹出窗口


                                            <p><p>我有一个棘手的任务。我有带有两个 tableView、按钮等的 TableUIViewController(父 UIViewController)。此 UIViewController 显示有关咖啡馆中表的信息。 </p>

<p>我还有另一个名为 MenuTableViewController 的 Controller (父级是 UITableViewController),它是显示菜单项列表的单独 View 。只有三个 UI 项 - 每个单元格中有两个标签和按钮。</p>

<p>想法:
我想以两种不同的方式使用这个 MenuTableViewController。</p>

<ol>
<li><p>如果从主菜单执行到此 View 的 segue - 只需显示菜单并允许用户编辑每个单元格。 Button.title = "打开"。</p></li>
<li><p>如果 View 是从 TableUIViewController 打开的 - 将按钮标题更改为“选择”,如果按下按钮以创建订单等,则返回到 MenuTableViewController。</p></li>
</ol>

<p>我发现执行 segue + prepare for segue 对我有用,但如果我使用 segue,我会遇到导航 Controller 的问题 - 我完全失去了“返回”按钮并且无法返回主菜单。 </p>

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

<ol>
<li><p>TableUIViewController 中的点击按钮</p></li>
<li><p>显示 MenuTableViewController</p></li>
<li><p>点击某个按钮</p></li>
<li><p>返回到 TableUIViewController - 理想情况下无需重新初始化,以保留所有变量的值。</p></li>
</ol>

<p>但我不明白如何在这里使用 AddSubview。有人可以指导我吗?或者提供一些例子。没发现什么好东西。</p>

<p>这是我的类(class):</p>

<p><strong>TableUIViewController</strong></p>

<pre><code>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&lt;GuestsTable&gt;?
    fileprivate var ordersTableFetchedResultsController: NSFetchedResultsController&lt;OrdersTable&gt;?


    //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 &gt; 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 = &#34; - &#34;
      }
      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&lt;GuestsTable&gt; = GuestsTable.fetchRequest()
      request.predicate = NSPredicate(format: &#34;table= %@&#34;, currentTableSession!)
      request.sortDescriptors =
      guestsTableFetchedResultsController = NSFetchedResultsController&lt;GuestsTable&gt;(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&lt;OrdersTable&gt; = OrdersTable.fetchRequest()
      request.sortDescriptors =
      ordersTableFetchedResultsController = NSFetchedResultsController&lt;OrdersTable&gt;(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
      try? ordersTableFetchedResultsController?.performFetch()
      tableView?.reloadData()
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
      if tableView == self.guestsTableView {
            let cell = tableView.dequeueReusableCell(withIdentifier: &#34;guestCell&#34;, for: indexPath) as! GuestAtTableTableViewCell
            if let guest = guestsTableFetchedResultsController?.object(at: indexPath) {
                cell.guestNameLabel.text = guest.guestName
                cell.openTimeLabel.text = &#34;Пришел: &#34; + myGenericFunctions.convertDate(inputDate: guest.openTime!)
                if let closeTime = guest.closeTime {
                  cell.closeTimeLabel.text = &#34;Ушел: &#34; + 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: &#34;orderCell&#34;, for: indexPath)
            return cell
      }
    }

    func numberOfSections(in tableView: UITableView) -&gt; 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) -&gt; Int {
      if tableView == self.guestsTableView {
            if let sections = guestsTableFetchedResultsController?.sections, sections.count &gt; 0 {
                return sections.numberOfObjects
            }
            else {
                return 0
            }
      }
      else if tableView == self.ordersTableView {
            if let sections = ordersTableFetchedResultsController?.sections, sections.count &gt; 0 {
                return sections.numberOfObjects
            }
            else {
                return 0
            }
      }
      else {return 0}
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -&gt; String? {
      if tableView == self.guestsTableView {
            if let sections = guestsTableFetchedResultsController?.sections, sections.count &gt; 0 {
                return sections.name
            }
            else {
                return nil
            }
      }
      else if tableView == self.ordersTableView {
            if let sections = ordersTableFetchedResultsController?.sections, sections.count &gt; 0 {
                return sections.name
            }
            else {
                return nil
            }
      }
      else {return nil}

    }

    func sectionIndexTitles(for tableView: UITableView) -&gt; ? {
      if tableView == guestsTableView {
            return guestsTableFetchedResultsController?.sectionIndexTitles
      }
      else {
            return ordersTableFetchedResultsController?.sectionIndexTitles
      }
    }

    func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -&gt; 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 == &#34;openMenuToAddOrder&#34; {
            if let menuTVC = segue.destination as? MenuTableViewController {
                menuTVC.isOpenedFromTable = true
                menuTVC.currentTableSession = currentTableSession
                menuTVC.currentTable = currentTable
            }
      }
    }*/
}
</code></pre>

<p><strong>ManuTableViewController:</strong></p>

<pre><code>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&lt;MenuTable&gt;?

    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: &#34;returnToTableView&#34;, 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&lt;MenuTable&gt; = MenuTable.fetchRequest()
      request.sortDescriptors =
      fetchedResultsController = NSFetchedResultsController&lt;MenuTable&gt;(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
      fetchedResultsController?.delegate = self
      try? fetchedResultsController?.performFetch()
      tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: &#34;menuCell&#34;, 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(&#34;Выбрать&#34;, for: UIControlState.normal)
            } else {
                cell.button.setTitle(&#34;Открыть&#34;, 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 == &#34;returnToTableView&#34; {
            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) -&gt; Int {
      return fetchedResultsController?.sections?.count ?? 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
      if let sections = fetchedResultsController?.sections, sections.count &gt; 0 {
            return sections.numberOfObjects
      }
      else {
            return 0
      }
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -&gt; String? {
      if let sections = fetchedResultsController?.sections, sections.count &gt; 0 {
            return sections.name
      }
      else {
            return nil
      }
    }

    override func sectionIndexTitles(for tableView: UITableView) -&gt; ? {
      return fetchedResultsController?.sectionIndexTitles
    }

    override func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -&gt; Int {
      return fetchedResultsController?.section(forSectionIndexTitle: title, at: index) ?? 0
    }
}
</code></pre>

<p><strong>更新:</strong>
这是我的 Storyboard。我感觉我没有正确使用导航 Controller 。但是在 View 之间没有一些 Controller- 后退按钮不会出现。并对图像中的俄语文本感到抱歉。
<a href="/image/Ok67Q.jpg" rel="noreferrer noopener nofollow"><img src="/image/Ok67Q.jpg" alt="enter image description here"/></a> </p>

<p><strong>标记为已解决后更新:</strong></p>

<p>我删除了 performSegue 并将 Controller 中的 segues 放到按钮本身。现在导航 Controller 保持返回按钮应有的状态。
还将更新 UI 功能移动到 viewWillAppear 以在 segues 后保持表格更新。</p>

<pre><code>override func viewWillAppear(_ animated: Bool) {
    updateGuestsTableView()
    updateOrdersTableView()
    updateLabels()
    updateOrdersTableView()
}
</code></pre>

<p>另一个更新,现在它完全可以按照我的意愿运行。
我已添加到由 Menu Cell Button 调用的函数以返回到先前的 ViewController(与 Back 按钮相同):</p>

<pre><code>    //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
      }
    }
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>听起来你想要这样的结构:</p>

<p> <a href="/image/AObIk.png" rel="noreferrer noopener nofollow"><img src="/image/AObIk.png" alt="enter image description here"/></a> </p>

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

<p>如果您选择“编辑食物菜单”,那么您的食物菜单代码应显示“编辑”作为表格中每一行的按钮标题。点击“编辑”将带您进入“编辑菜单项” View 。</p>

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

<p>因为所有 View 都是同一个导航 Controller 结构的一部分,所以您将始终能够通过选择导航栏上的标准“<返回”按钮来“返回堆栈”。</p>

<p>希望这有点道理:)</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Swift 3.1 UITableViewController 作为 subview 或弹出窗口,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/44309653/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/44309653/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Swift 3.1 UITableViewController 作为 subview 或弹出窗口