每当我在应用程序中搜索时,都会显示正确的结果,但是当我点击搜索的单元格时,在执行搜索之前,它始终会播放表格的第一个索引。我试图在我的didselectcell中使用isSearching Bool,但似乎无法正常工作。
import UIKit import AVFoundation import AVKit class FordFlixViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate { let avPlayerViewController = AVPlayerViewController() var player: AVPlayer! var flix = [Courses]() var currentArray = [Courses]() let urlString = "http://homevideosdata.192.168.1.19.xip.io/getMoreClasses.php" @IBOutlet weak var searchBar: UISearchBar! @IBOutlet weak var homeVidsBtn: UIButton! @IBOutlet weak var grrr: UITableView! var isSearching = false lazy var refreshControl: UIRefreshControl = { let refreshControl = UIRefreshControl() refreshControl.tintColor = .black refreshControl.addTarget(self, action: #selector(requestData), for: .valueChanged) return refreshControl }() override func viewDidLoad() { super.viewDidLoad() setUpSearchBar() requestData() // Do any additional setup after loading the view. } private func setUpSearchBar() { searchBar.showsScopeBar = true searchBar.selectedScopeButtonIndex = 0 searchBar.delegate = self self.grrr.tableHeaderView = searchBar currentArray = flix } func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { guard !searchText.isEmpty else { isSearching = true currentArray = flix grrr.reloadData() return } currentArray = flix.filter({ video -> Bool in video.title.contains(searchText) }) grrr.reloadData() } func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) { } let searchController = UISearchController(searchResultsController: nil) @objc func requestData() { print("requesting data") fetchJSON() let deadline = DispatchTime.now() + .microseconds(700) DispatchQueue.main.asyncAfter(deadline: deadline) { self.refreshControl.endRefreshing() } } func fetchJSON() { guard let url = URL(string: urlString) else { return } URLSession.shared.dataTask(with: url) { (data, response, err) in DispatchQueue.main.async { if let err = err { print("Failed to get data from URL:", err) return } else { print("Loaded URL") } guard let data = data else { return } do { let decoder = JSONDecoder() self.flix = try decoder.decode([Courses].self, from: data) self.grrr.reloadData() print(self.flix) } catch let jsonErr { print("Failed to decode JSON", jsonErr) } } }.resume() } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return currentArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FlixTableViewCell let sweet = currentArray[indexPath.row] let bgColorView = UIView() bgColorView.backgroundColor = UIColor.black cell.selectedBackgroundView = bgColorView cell.titleLbl.text = sweet.title if let profileImageUrl = sweet.image { let url = URL(string: profileImageUrl) URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in if error != nil { print(error) return } DispatchQueue.main.async { cell.productImage.image = UIImage(data: data!) } }).resume() } return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if isSearching == false { let selectedCell = flix[indexPath.row].location let url = selectedCell // Create an AVPlayer, passing it the HTTP Live Streaming URL. let player = AVPlayer(url: URL(string: url)!) // Create a new AVPlayerViewController and pass it a reference to the player. let controller = AVPlayerViewController() controller.player = player // Modally present the player and call the player's play() method when complete. present(controller, animated: true) { player.play() } } else { if isSearching == true { let selectedCellTwo = currentArray[indexPath.row].location let url = selectedCellTwo // Create an AVPlayer, passing it the HTTP Live Streaming URL. let playerTwo = AVPlayer(url: URL(string: url)!) // Create a new AVPlayerViewController and pass it a reference to the player. let controller = AVPlayerViewController() controller.player = playerTwo // Modally present the player and call the player's play() method when complete. present(controller, animated: true) { playerTwo.play() } } } } }
我认为问题在于您正在跟踪自己是否在搜索和操作源数据数组。
我有一个示例游乐场代码段,我已将其用于其他一些答案,该示例向您展示了如何更有效地执行此操作,并提供了一些方便的辅助功能以使其变得更容易。
我认为对您有利的关键部分是:
仅将搜索结果保留一个单独的数组,仅在搜索处于活动状态时使用
var filteredNames = [String]()
确保您调整搜索时是否使用的计数和行
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if isFiltering() { return filteredNames.count } else { return names.count } } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell() // don't do this, i am for example. var name: String if isFiltering() { name = filteredNames[indexPath.row] } else { name = names[indexPath.row] } cell.textLabel?.text = name return cell }
您可以使用以下帮助器功能来帮助您。
func searchBarIsEmpty() -> Bool { // Returns true if the text is empty or nil return searchController.searchBar.text?.isEmpty ?? true } func isFiltering() -> Bool { return searchController.isActive && !searchBarIsEmpty() }
完整的UISearchController示例(操场)
import UIKit import PlaygroundSupport class ViewController: UITableViewController { let searchController = UISearchController(searchResultsController: nil) var names = [ "John", "Terry", "Martin", "Steven", "Michael", "Thomas", "Jason", "Matthew" ] var filteredNames = [String]() override func viewDidLoad() { super.viewDidLoad() self.title = "Search Example" searchController.searchResultsUpdater = self searchController.obscuresBackgroundDuringPresentation = false searchController.searchBar.placeholder = "Search" navigationItem.searchController = searchController definesPresentationContext = true } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if isFiltering() { return filteredNames.count } else { return names.count } } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell() // don't do this, i am for example. var name: String if isFiltering() { name = filteredNames[indexPath.row] } else { name = names[indexPath.row] } cell.textLabel?.text = name return cell } func searchBarIsEmpty() -> Bool { // Returns true if the text is empty or nil return searchController.searchBar.text?.isEmpty ?? true } func isFiltering() -> Bool { return searchController.isActive && !searchBarIsEmpty() } func filterContentForSearchText(_ searchText: String, scope: String = "All") { filteredNames = names.filter({( name : String) -> Bool in return name.lowercased().contains(searchText.lowercased()) }) tableView.reloadData() } } extension ViewController: UISearchResultsUpdating { func updateSearchResults(for searchController: UISearchController) { filterContentForSearchText(searchController.searchBar.text!) } } let vc = ViewController() let nav = UINavigationController() nav.viewControllers = [vc] PlaygroundPage.current.liveView = nav