未调用 DidSelectRow 函数

Posted

技术标签:

【中文标题】未调用 DidSelectRow 函数【英文标题】:DidSelectRow function is not called 【发布时间】:2020-08-03 15:44:22 【问题描述】:

我正在尝试实现 didSelectRow 函数并执行 segue,但是在运行单元格选择时没有任何反应。

我创建了一个也不运行的打印语句,这证明该函数似乎没有被触发。为什么会这样?

我检查了标识符是否正确,并研究了几个小时,经历了许多堆栈溢出线程,但运气不佳。

import UIKit
import CoreData
    
    class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 
        
        let viewController = ListNameViewController()
        let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext
        var itemChoosen = 0
        
        override func viewDidLoad() 
            super.viewDidLoad()
            homeListsTableView.delegate = self
            homeListsTableView.dataSource = self
            viewController.loadList()
            
        
        
        @IBOutlet weak var homeListsTableView: UITableView!
        
        @IBAction func templatesButton(_ sender: Any) 
            
            tabBarController?.selectedIndex = 2
        
        
        @IBAction func allListsButton(_ sender: Any) 
            tabBarController?.selectedIndex = 0
            
        
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
            
            return viewController.listName.count
        
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            let result = viewController.listName[indexPath.row]
            cell.textLabel?.text = ("\(String(result.listName!))")
            return cell
            
        
        
        func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) 
            if editingStyle == .delete 
                context!.delete(viewController.listName[indexPath.row])
                viewController.listName.remove(at: indexPath.row)
                viewController.saveList()
                homeListsTableView.reloadData()
                
            
        
        
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
            performSegue(withIdentifier: "items2", sender: self)
            print("selected")
        
        
        override func viewWillAppear(_ animated: Bool) 
            super.viewWillAppear(false)
            viewController.loadList()
            homeListsTableView.reloadData()
        
        
        override func viewDidAppear(_ animated: Bool) 
            super.viewDidAppear(true)
            homeListsTableView.reloadData()
        
        
    

ListNameViewController: 

import UIKit
import CoreData

class ListNameViewController: UIViewController, UITableViewDelegate 
    
    let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext
    var listName : [ListName] = []

    override func viewDidLoad() 
        super.viewDidLoad()
        
        createButtonChange.isEnabled = false
        
        //Objective-C Line used to keep checking if the text field is vaild before enabling the submit button
        
        listNameValue.addTarget(self, action: #selector(textValidation), for: UIControl.Event.editingChanged)
    
    
    @IBOutlet weak var listNameValue: UITextField!
    @IBOutlet weak var locationOption: UITextField!
    @IBOutlet weak var createButtonChange: UIButton!
    
    @objc func textValidation() 
        //Text Field Validation check before button is enabled
        if listNameValue.text!.isEmpty 
            createButtonChange.isEnabled = false
         else 
            createButtonChange.isEnabled = true
        
    
    
    
    // Create a new List
    
    @IBAction func createButton(_ sender: Any) 
        
        let newList = ListName(context: context!)
        newList.listName = listNameValue.text
        saveList()
        self.navigationController!.popViewController(animated: true)
        viewWillAppear(false)
    
    
    
    
    func saveList() 
        
        do 
          try context!.save()
         catch 
          print("Error saving context \(error)")
      
        
    
    
    func loadList() 
          
          let request : NSFetchRequest<ListName> = ListName.fetchRequest()
          
          do
            listName = try context!.fetch(request)
           catch 
              print("Error loading categories \(error)")
          
      
    
    //Pass data to the HomeViewController
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
       // let vc = segue.destination as! HomeViewController
        
    

// 注释掉核心数据,只用一个普通的数组进行测试。

【问题讨论】:

是否调用了其他 UITableViewDataSource 方法?喜欢cellForRowAtviewController 是什么,它与您的 tableView 完全不同吗?你在混合元素吗? ListNameViewController 用于向 tableView 添加一个新项目,这样做是为了让 homeViewController 可以访问并显示来自 listName 数组的数据。 你能检查 numberOfRowsInSection 中返回的值吗? 在故事板环境中,默认初始化器ListNameViewController() 永远不会返回故事板中的实例。无论如何,在另一个视图控制器中定位数据源是一种不好的做法。 【参考方案1】:

您是否在情节提要中为 tableview 添加了 segue ?在这种情况下,没有调用 didSelect,而是调用了 tableview 控制器的 prepare(for segue)。

【讨论】:

我不完全确定你的意思,故事板中有一个包含标识符 items2 的 segue,它是使用 perform segue 的 didSelect 函数中使用的标识符。如果 didSelect 没有被调用,我如何让它从为 segue 做准备中调用? 所以在很长一段时间后,似乎调用了 didSelectRow 函数,但只是长按,有谁知道为什么会这样?【参考方案2】:

好的解决了 - 页面上有一个胭脂轻击手势识别器。删除它并一键工作。我已经看到,如果您希望保留手势,只需在函数顶部添加这行代码:

 tap.cancelsTouchesInView = false

花了三天,但我到了那里。感谢您的帮助!

【讨论】:

以上是关于未调用 DidSelectRow 函数的主要内容,如果未能解决你的问题,请参考以下文章

UITableView didSelectRow 未调用

如何快速从另一个控制器调用函数

UIPickerView - 第一行选择不调用 didSelectRow

我们可以在 ios swift 的 indexpath 的 didSelectRow 中异步调用 api

DidSelectRow 不工作

选择器视图 - 文本字段未更新