选择过滤的搜索结果
Posted
技术标签:
【中文标题】选择过滤的搜索结果【英文标题】:Select Filtered search results 【发布时间】:2018-11-02 13:05:33 【问题描述】:每当我在我的应用程序中搜索时,我都会显示正确的结果,但是当我点击我搜索的单元格时,它总是在我进行搜索之前播放表格的第一个索引。我正在尝试在我的 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()
【问题讨论】:
请删除所有与您的问题相关的代码。请阅读minimal reproducible example 【参考方案1】:我认为问题在于您是否在跟踪自己是否在搜索并操作源数据数组。
我有一个示例游乐场 sn-p 我已用于其他一些答案,它向您展示了如何更有效地做到这一点,并有一些方便的辅助功能使其更容易。
我认为对您有益的关键部分是:
只保留一个单独的搜索结果数组,仅在搜索处于活动状态时使用
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
【讨论】:
以上是关于选择过滤的搜索结果的主要内容,如果未能解决你的问题,请参考以下文章