代码之家  ›  专栏  ›  技术社区  ›  CristianMoisei

存储在数组中并显示在uitableview中的uisearchbar结果干扰了我的didselectrowat indexpath方法(swift)

  •  0
  • CristianMoisei  · 技术社区  · 6 年前

    我有一个uitableview,它由titles数组中的项填充,我设置了它,以便在调用didselectrowat indexpath时,名为arrayindex的变量将更改为indexpath,下一个vc的内容也将更改。

    因此,如果用户点击:

    • 第0行>vc将具有标题0、定义0和链接0
    • 第12行>VC将具有标题12、定义12和链接12

    但是,我有一个搜索栏,它将筛选的结果存储在search results数组中,并在tableview中显示。执行搜索时,数组索引将不再对应,因此如果搜索查询将tableview更改为

    • 第0行的标题4>VC将具有标题0、定义0和链接0
    • 第1行的标题5>VC将具有标题1、定义1和链接1
    • 第2行的标题18>VC将具有标题2、定义2和链接2

    我理解为什么它不能按预期工作,但我不知道如何更新我的逻辑来修复它。思想?这是我的代码:

    列表控制器:

    import UIKit
    
    var arrayIndex = 0 // is used in DefinitionController to determine which title/definition/link to show.
    var isSearching = false
    
    class ListController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {
    
        @IBOutlet var tableView: UITableView!
        @IBOutlet var searchBar: UISearchBar!
    
        // Search Delegate
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            if searchText == "" {
                isSearching = false
                tableView.reloadData()
            } else {
                isSearching = true
                searchResults = (titles.filter { $0.lowercased().contains(searchText.lowercased()) })
                tableView.reloadData()
            }
        }
    
        //Table Delegate
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    
            if isSearching == true {
                // code to run if searching is true
            } else {
                arrayIndex = indexPath.row // assigns the value of the selected tow to arrayIndex
            }
    
            performSegue(withIdentifier: "segue", sender: self)
            tableView.deselectRow(at: indexPath, animated: true)
        }
    
        // Table Data Source
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if isSearching == true {
                return searchResults.count
            } else {
                return titles.count
            }
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
            // Cell Data Source
            let cell = UITableViewCell()
    
            if isSearching == true {
                cell.textLabel?.text = searchResults[indexPath.row]
            } else {
                cell.textLabel?.text = titles[indexPath.row]
            }
    
            // Cell Visual Formatting
            cell.backgroundColor = UIColor(red:0.05, green:0.05, blue:0.07, alpha:0)
            cell.textLabel?.textColor = UIColor.white
            cell.textLabel?.font = UIFont(name: "Raleway", size: 18)
            cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
    
    //        if (cell.isSelected) {
    //            cell.backgroundColor = UIColor.cyan
    //        }else{
    //            cell.backgroundColor = UIColor.blue
    //        }
    
            return cell
        }
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.title = "\(titles.count) Definitions"
    
            // TextField Color Customization
            let searchBarStyle = searchBar.value(forKey: "searchField") as? UITextField
            searchBarStyle?.textColor = UIColor.white
            searchBarStyle?.backgroundColor = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0.05)
    
        }   
    }
    

    定义控制器:

    import UIKit
    
    class DefinitionController: UIViewController {
    
        @IBOutlet var definitionTitle: UILabel!
        @IBOutlet var definitionBody: UILabel!
        @IBOutlet var definitionSources: UILabel!
    
        // Open link in Safari
        @objc func tapFunction(sender:UITapGestureRecognizer) {
            print("tap working")
            if let url = URL(string: "\(links[arrayIndex])") {
                UIApplication.shared.openURL(url)
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            definitionTitle.text = titles[arrayIndex]
            definitionBody.text = definitions[arrayIndex]
    
    
            self.title = "" // Used to be \(titles[arrayIndex])
    
            // Sources Link
            let tap = UITapGestureRecognizer(target: self, action: #selector(DefinitionController.tapFunction))
            definitionSources.addGestureRecognizer(tap)
    
        }
    
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Do2    6 年前

    尝试使用一个字典,其中键是您的标题,其值是一个包含定义和链接的字典,以及一个数组,您将在其中存储搜索结果,即搜索的键。

    var dictionary = ["title 0":["definition 0", "Link 0"], "title 1": ["definition 1", "Link 1"]]
    
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchText == "" {
            isSearching = false
            tableView.reloadData()
        } else {
            isSearching = true
            for (key, value) in dictionary {
           if key==searchText{
           resultsArray.append(key)
    }
    }
            tableView.reloadData()
        }
    }
    

    现在当你在 List Controller 让它知道你想在下一个VC中初始化和加载哪个键的详细信息:

     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     let DefinitionViewController = self.storyboard?.instantiateViewController(withIdentifier: "DefinitionViewController") as! DefinitionViewController
    
            //initialise data for the view controller
            ListViewController.initDetails(forKey: resultsArray[indexPath.row])
    
            performSegue(withIdentifier: "segue", sender: self)
            tableView.deselectRow(at: indexPath, animated: true)
     }
    

    在你 Definition Controller 初始化详细信息:

    func initDetails(forKey key: String) {
        definitionBody.text=dictionary[key]![0]
        definitionSources.text=dictionary[key]![1]
    }
    
        2
  •  0
  •   CristianMoisei    6 年前

    我想到了一个在我看来相当肮脏的解决方案,因为它需要保留两组标题,所以我仍然好奇是否有人知道更好的方法,但这确实有效:

    如果在didselectrowat indexpath下进行搜索(以避免在不需要时调用开关),我创建了一个开关,它基本上检查所选单元格的文本并相应地设置arrayindex的值。

    let selectedCell = tableView.cellForRow(at: indexPath)?.textLabel!.text ?? "Undefined"
    
           switch selectedCell {
           case "Anger": arrayIndex = 0
           case "Anguish": arrayIndex = 1
           case "Anxiety": arrayIndex = 2
           case "Annoyance": arrayIndex = 3
           case "Apathy": arrayIndex = 4
           default: print("Undefined Search Query")
           }
    

    titles数组最终将有大约55个元素,我曾希望将所有数据保存在单独的data.swift文件中,但这是迄今为止我唯一的解决方案。