我创建了一个
UICollectionView
,其中包含来自 API 的数据,它显示标题和海报图像。 UICollection
可以正常显示两者。
我正在尝试实现一个根据标题进行搜索的
UISearchBar
。我遇到的问题是使用 UICollectionView
时 UISearchBar
没有响应或更新。
这是我当前的代码:
import UIKit
import AFNetworking
class FilmsViewController: UIViewController, UICollectionViewDelegate,
UICollectionViewDataSource, UICollectionViewDelegateFlowLayout,
UISearchBarDelegate, UISearchControllerDelegate {
var films: [NSDictionary]?
var filteredFilms: [NSDictionary]?
var searching:Bool = false
override func viewDidLoad() {
super.viewDidLoad()
filmsTable.dataSource = self
filmsTable.delegate = self
loadFilms()
}
override func viewDidAppear(_ animated: Bool) {
navigationItem.titleView = imageView
}
//SEARCH BAR
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
self.filteredFilms?.removeAll()
if searchText != "" {
searching = true
for film in self.films! {
if (film["title"] as! String).contains(searchText.lowercased()) {
self.filteredFilms?.insert(film, at: (filteredFilms?.endIndex)!)
}
}
} else {
searching = false
self.filteredFilms = self.films
}
filmsTable.reloadData()
}
/*
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
let search = searchBar.text!
if search.isEmpty {
self.filmsTable.reloadData()
}
else {
// let search = searchBar.text!
filteredFilms = films!.filter({ (text) -> Bool in
//Access the title and sectors
let filmTitle = text["title"] as! NSString
//Create a range for both
let range1 = filmTitle.range(of: search, options: NSString.CompareOptions.caseInsensitive)
self.filmsTable.reloadData()
return range1 != nil
})
self.filmsTable.reloadData()
}
}
*/
//Collection View Layout
func collectionView(_ _collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if searching {
return filteredFilms?.count ?? 0
} else {
return films?.count ?? 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = filmsTable.dequeueReusableCell(withReuseIdentifier: "filmCell", for: indexPath) as! FilmCell
if searching {
let film = filteredFilms![indexPath.row]
let title = film["title"] as! String
cell.titleLabel.text = title
} else {
let film = films![indexPath.row]
let title = film["title"] as! String
cell.titleLabel.text = title
}
return cell
}
//End Collection View Layout
//Parse Film API
func loadFilms() {
let apiKey = ""
let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)&language=en-US&page=1")
let request = URLRequest(
url: url! as URL,
cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
timeoutInterval: 10 )
let session = URLSession (
configuration: URLSessionConfiguration.default,
delegate: nil,
delegateQueue: OperationQueue.main
)
let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
if let data = dataOrNil {
if let resposeDictionary = try! JSONSerialization.jsonObject(with: data, options:[]) as? NSDictionary {
self.films = resposeDictionary["results"] as? [NSDictionary]
print("response: \(resposeDictionary)")
}
}
self.filteredFilms = self.films
self.filmsTable.reloadData()
})
task.resume()
}
//End Parse Film API
}
编辑:我也尝试过这个。我在
"filmTable =" line
: 处收到错误
“无法使用“String”类型的索引为“[NSDictionary]”类型的值添加下标。
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
searching = false
filmsTable.reloadData()
} else {
searching = true
let filmTitle = films!["title"] as! NSString
filteredFilms = films!.filter({$0.filmTitle.range(of: searchBar.text!) != nil})
filmsTable.reloadData()
}
}
不确定您的代码中到底在哪里遇到了问题。但是,我可以给您一些建议和您正在尝试做的事情的可行示例。
这是您想要执行的操作的示例:
class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource, UISearchBarDelegate {
lazy var collectionView : UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .white
cv.dataSource = self
cv.delegate = self
return cv
}()
var films = [["title" : "one"], ["title" : "two"], ["title" : "three"]]
var filteredFilms = [Dictionary<String, String>]()
let searchBar = UISearchBar()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(searchBar)
searchBar.translatesAutoresizingMaskIntoConstraints = false
searchBar.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 60).isActive = true
searchBar.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
searchBar.heightAnchor.constraint(equalToConstant: 60).isActive = true
searchBar.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
self.view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.topAnchor.constraint(equalTo: self.searchBar.bottomAnchor).isActive = true
collectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
self.searchBar.delegate = self
self.filteredFilms = films
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return filteredFilms.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 100)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
self.filteredFilms = films
self.collectionView.reloadData()
} else {
self.filteredFilms = films.filter({($0["title"]?.contains(searchText.lowercased()))!})
print(self.filteredFilms.count)
self.collectionView.reloadData()
}
}
}
class Cell : UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
func setupViews() {
self.backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
您唯一需要做的就是:
searchController.obscuresBackgroundDuringPresentation = false
尝试:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.filteredFilms?.removeAll()
if searchText != "" {
searching = true
for film in self.films! {
if (film["title"] as! String).contains(searchText.lowercased()) {
self.filteredFilms?.insert(film, at: (filteredFilms?.endIndex)!)
}
}
} else {
searching = false
self.filteredFilms = self.films
}
filmsTable.reloadData()
}
UISearchBarDelegate:
(_ searchBar:...
不是(searchBar:...
试试这个希望它会起作用:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == nil || searchBar.text == "" {
searching = false
filmsTable.reloadData()
} else {
searching = true
filteredFilms = films.filter({$0.["title"].range(of: searchBar.text!) != nil})
filmsTable.reloadData()
}
}