如何制作搜索结果?UICollection View中的搜索栏



我解析了一个来自iTunes API的数据模型:

struct AlbumData: Codable {

let results: [Result]

}
struct Result: Codable {

let artistName, collectionName: String
let trackCount: Int
let releaseDate: String
let artworkUrl100: String

}
struct AlbumModel {

let albumsResult: [Result]

}

,这是NetworkService代码:

import Foundation
protocol NetworkServiceDelegate {
func updateInfo (_ manager: NetworkService, album: AlbumModel)
func errorInfo (error: Error)
}
struct NetworkService {

var delegate: NetworkServiceDelegate?

func fetchAlbums () {
let urlString = "https://itunes.apple.com/search?term=eminem&limit=8&entity=album"
performRequest(with: urlString)
}

func performRequest(with urlString: String) {

if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
delegate?.errorInfo(error: error!)
print("Debuggg error (LocalizedError.self)")
}
if let safeData = data {
if let albums = self.parseJSON(safeData) {
delegate?.updateInfo(self, album: albums)
print("succses - (albums)")
}
}
}
task.resume()
}
}

func parseJSON(_ data: Data) -> AlbumModel? {

let decoder = JSONDecoder()

do {
let decodedData = try decoder.decode(AlbumData.self, from: data)
let result = decodedData.results
let album = AlbumModel(albumsResult: result)
return album
} catch {
print(error)
return nil
}
}

}

之后,我将这个数据添加到数组中:

var albums: [AlbumModel] = []

现在我有了这样的数组:

[Itunes_Albums.AlbumModel(albumsResult: [Itunes_Albums_.Result(artistName: "Eminem", collectionName: "The Eminem Show", trackCount: 20, releaseDate: "2002-01-01T08:00:00Z", artworkUrl100: "https://is5-ssl.mzstatic.com/image/thumb/Music115/v4/61/d5/0a/61d50a3d-4a27-187a-d16f-6b8ce4b62560/source/100x100bb.jpg"), Itunes_Albums_.Result(artistName: "Eminem", collectionName: "Recovery (Deluxe Edition)", trackCount: 19, releaseDate: "2010-06-21T07:00:00Z", artworkUrl100: "https://is5-ssl.mzstatic.com/image/thumb/Music125/v4/f1/40/ce/f140ce18-f176-7cf9-c220-3958d7747ae6/source/100x100bb.jpg")

之后,我将这些数据显示到集合视图

我SearchViewController

之后,我想写一些字符搜索栏(名称的专辑)和显示专辑,但它不工作。

我可以显示所有的代码:

import UIKit
class SearchViewController: UIViewController {
@IBOutlet weak var albumCollectionView: UICollectionView!

var albums: [AlbumModel] = []
var albumsForSearch: [AlbumModel] = []
var networkService = NetworkService()

override func viewDidLoad() {
super.viewDidLoad()

title = "Search"
registerCells()
networkService.delegate = self
networkService.fetchAlbums()
}

private func registerCells() {
albumCollectionView.register(UINib(nibName: AlbumCollectionViewCell.identifier, bundle: nil), forCellWithReuseIdentifier: AlbumCollectionViewCell.identifier)
}
}
//MARK: - AlbumManagerDelegate
extension SearchViewController: NetworkServiceDelegate {

func updateInfo(_ manager: NetworkService, album: AlbumModel) {
DispatchQueue.main.async {
self.albums.append(album)
self.albumsForSearch = self.albums
print("CHEEEEEK - (self.albums)")
self.albumCollectionView.reloadData()

}
}

func errorInfo(error: Error) {
print(error)
}
}
//MARK: - UICollectionViewDelegate, UICollectionViewDataSource
extension SearchViewController: UICollectionViewDelegate, UICollectionViewDataSource {

func numberOfSections(in collectionView: UICollectionView) -> Int {
return albums.count
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return albums[section].albumsResult.count       
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AlbumCollectionViewCell.identifier, for: indexPath)
as! AlbumCollectionViewCell

let jData = albums[indexPath.section].albumsResult[indexPath.item]
cell.albumNameLabel.text = jData.collectionName
cell.artistNameLabel.text = jData.artistName
cell.numberOfTracksLabel.text = "(jData.trackCount) song(s)"
cell.albumImage.load(urlString: "(jData.artworkUrl100)")
cell.dateOfRelease.text = jData.releaseDate.substring(toIndex: 10)
return cell
}
}
//MARK: - UISearchBarDelegate
extension SearchViewController: UISearchBarDelegate, UISearchResultsUpdating {

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

let searchView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CollectionReusableView", for: indexPath)
return searchView
}

func updateSearchResults(for searchController: UISearchController) {
if let searchText = searchController.searchBar.text?.lowercased(), !searchText.isEmpty {
albumsForSearch = albums.filter { album -> Bool in
return album.albumsResult.contains { item -> Bool in item.collectionName.lowercased().contains(searchText)
}
}
albumCollectionView.reloadData()
} else {
albumsForSearch = albums
}
}
}

当我在搜索栏中输入一些字符时,没有任何变化

不知道你到底在纠结什么,所以我只是指出一些事情,希望这能解决你的问题。

首先,我不知道你的AlbumModel长什么样。也许您可以显示这段代码。但是看起来每个实例包含不止一个albumsResult。您是否期望在这个数组中的albumsResult中只有一个对象?

如果没有,我发现这行真的很奇怪item.albumsResult[0]。有可能发生崩溃。因此,我的答案并不假设该数组中总是有一个(且只有一个)项。

第二,我也觉得这个很奇怪:

} else {
searching = false
albumsForSearch.removeAll()
albumsForSearch = albums
}

每次找不到结果时,都要重置数组。我不确定我能想出一个合理的理由,为什么你会想要那样做。

也许这段代码就是你需要的:

if let searchText = let searchText = searchController.searchBar.text?.lowercased(), !searchText.isEmpty {
// Search text means filter results
albumsForSearch = albums.filter { album -> Bool in 
return album.albumResult.contains { item -> Bool in 
item.collectionName.lowercased().contains(searchText)  
}
}
} else {
// No search text means display everything
albumsForSearch = albums
}

然后根据albumsForSearch

创建tableview分段和行

最新更新