【问题标题】:Nothing Happens When UITableView is Clicked (trying to send data between views)单击 UITableView 时没有任何反应(尝试在视图之间发送数据)
【发布时间】:2018-11-16 17:29:43
【问题描述】:

所以我有一个两页应用程序。该应用程序的目的是用户可以存储费用。他们记录了nameamount(属性),这些数据存储在Expenses(实体)中。我已经弄清楚如何创建核心数据值、删除和检索。我现在正在努力更新。这将通过用户在存储费用的第一个视图 (ExpensesViewController) 中点击一个表来工作,这会将他们带到第二个视图 (EditExpensesViewController),在那里他们可以将值更新回核心数据。我被困在视图之间的这种“数据传输”上。

我正在使用情节提要并通过“show”将第一个视图连接到第二个视图,并将 segue 标识符设置为“editExpense”。然而,当点击表格行时没有任何反应。知道为什么它不起作用以及我可能错过了什么吗? See here for GIF

ExpensesViewController

import UIKit
import CoreData

class ExpensesViewController: UIViewController {

    @IBOutlet weak var totalLabel: UILabel!
    @IBOutlet weak var tableView: UITableView!

    var expenses_array = [Expenses]()
    var send_array = [Expenses]()

    override func viewDidLoad(){
        super.viewDidLoad()
        retrieveExpenses()
    }

    func retrieveExpenses(){
        let fetchRequest: NSFetchRequest<Expenses> = Expenses.fetchRequest()
        do {
            let expenses = try PersistenceService.context.fetch(fetchRequest)
            self.expenses_array = expenses
            self.tableView.reloadData()

        } catch  {
            print(error.localizedDescription )
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "editExpense") {
            let secondViewController = segue.destination as! EditExpensesViewController
            secondViewController.send_array = send_array
        }
    }


}

extension ExpensesViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return expenses_array.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
        cell.textLabel?.text = expenses_array[indexPath.row].name
        cell.detailTextLabel?.text = expenses_array[indexPath.row].amount
        return cell
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == .delete) {

            let fetchRequest: NSFetchRequest<Expenses> = Expenses.fetchRequest()
            do {
                let result = try PersistenceService.context.fetch(fetchRequest)

                // Delete from Core Data and remove from the arrays then save
                if result.contains(expenses_array[indexPath.row]){
                    PersistenceService.context.delete(expenses_array[indexPath.row])
                    expenses_array = expenses_array.filter { $0 != expenses_array[indexPath.row] }
                    PersistenceService.saveContext()
                    self.getTotalExpenses()
                    self.tableView.reloadData()
                }

            } catch  {
                print(error.localizedDescription )
            }
        }
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        send_array = [self.expenses_array[indexPath.row]]
        self.performSegue(withIdentifier: "editExpense", sender: self)
    }

}

EditExpensesViewController

import UIKit
import CoreData

class EditExpensesViewController: UIViewController {

    var send_array = [Expenses]() // Defined from the previous view controller

    override func viewDidLoad() {
        super.viewDidLoad()
        print(send_array)

    }
}

【问题讨论】:

  • 如果你可以添加一张图片来表明你的 segue 的名字,除了向我们展示 segue 连接 ViewControllers 的位置。
  • prepare 中设置断点并检查条件是否为真
  • 是的,但这并没有向我们作为帮助者表明您的 segue 是您实际所说的名称,也没有向我们显示您所说的已连接的视图控制器。为了让我们诊断您的问题,我们需要查看与您的问题相关的所有工作部分。
  • @impression7vx 添加

标签: swift uitableview core-data


【解决方案1】:

首先在 viewDidLoad() 中符合 tableView 委托和数据源:

tableView.delegate = self
tableView.dataSource = self

从 stroyboard 中删除 segue,我们将使用代码显示控制器:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "editExpense") {
        let secondViewController = segue.destination as! EditExpensesViewController
        secondViewController.send_array = send_array
        // "someIdentifier" is the identifier of secondController in storyboard
         storyboard?.instantiateViewController(withIdentifier: "someIdentifier")
        present(secondViewController, animated: true, completion: nil)
    }
}

注意使用属性检查器将第二个控制器的情节提要标识符放在情节提要中

【讨论】:

  • @Nouman 将您的控制器扩展更改为:扩展 ExpensesViewController: UITableViewDataSource, UITableViewDelegate
  • @Nouman 右键单击​​情节提要上的 tableView 并关闭 tableview 委托和数据源引用
  • @Nouman 上次崩溃是因为您有两个对 tableview 的引用,一个来自 viewDidLoad,另一个来自故事板。
【解决方案2】:

问题是您的第一个视图控制器只是 UITableViewDataSource。这还不够。它也需要是 UITableViewDelegate。 didSelectRowAt 是委托方法,不是数据源方法,除非此视图控制器是表视图委托并且明确声明符合 UITableViewDelegate,否则不会被调用。

【讨论】:

    猜你喜欢
    • 2010-12-13
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    相关资源
    最近更新 更多