Результаты UISearchBar, хранящиеся в массиве и отображаемые в UITableView, связаны с моим методом didSelectRowAt indexPath (Swift) - PullRequest
0 голосов
/ 08 июня 2018

У меня есть UITableView, который заполняется элементами из массива титров, и я настроил его так, чтобы при вызове didSelectRowAt indexPath переменная с именем arrayIndex изменялась на indexPath и содержимое следующего VC изменялось.

Таким образом, если пользователь нажимает:

  • Строка 0> VC будет иметь заголовок 0, определение 0 и ссылку 0
  • Строка12> VC будет иметь заголовок 12, определение 12 и ссылку 12

Однако у меня есть панель поиска, которая сохраняет отфильтрованные результаты в массиве searchResults и отображает их в tableView.Когда поиск выполняется, индекс массива больше не будет соответствовать, поэтому, если поисковый запрос изменит представление таблицы на

  • Заголовок 4 в строке 0> VC будет иметь Заголовок 0, Определение 0 иСсылка 0
  • Заголовок 5 в строке 1> VC будет иметь заголовок 1, определение 1 и ссылку 1
  • Заголовок 18 в строке 2> VCбудет иметь заголовок 2, определение 2 и ссылку 2

Я понимаю, почему это не работает, как ожидалось, но я не уверен, как обновить мою логику, чтобы исправить это.Мысли?Вот мой код:

ListController:

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 ]

0 голосов
/ 08 июня 2018

Попробуйте использовать словарь, в котором ключом является ваш заголовок, а его значением является словарь, содержащий определение и ссылку, а также массив, в котором вы будете хранить результаты поиска, то есть искомые ключи.

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]
}
0 голосов
/ 08 июня 2018

Я подумал о том, что мне кажется довольно грязным решением, потому что оно требует сохранения двух наборов заголовков, поэтому мне все еще любопытно, если кто-нибудь знает лучший способ, но это работает:

Еслиища (чтобы не вызывать переключатель, если он не нужен), под 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")
       }

Массив заголовковв конечном итоге будет иметь около 55 элементов, и я надеялся сохранить все данные в отдельном файле Data.swift, но это единственное решение, которое у меня есть.

...