gpt4 book ai didi

ios - UISearchBar 似乎返回正确的计数,但不是正确的行

转载 作者:行者123 更新时间:2023-11-28 09:40:09 27 4
gpt4 key购买 nike

我正在尝试在我的应用中实现搜索功能。现在,我只是尝试按我的 JSON 的 State 值进行搜索,尽管我最终还想包括 Category。总共有 9 行,前 7 行是 State=AZ,后 2 行是 State=CA。当我搜索“KK”时,表格是空的,这是有道理的。但是,当我搜索“CA”时,我得到了我预期的两行,但它们是 JSON 中的前两行,它们都是 AZ,而不是它应该是的两行 CA。

我怀疑我的问题出在我的 filterContentForSearchText 函数中的某处,但由于我不确定您到底需要哪个代码,这里是 ViewController(我认为问题所在的函数位于结束):

import UIKit
import os.log
import Foundation

class BonusListViewController: UITableViewController {

var bonuses = [JsonFile.JsonBonuses]()
var filteredBonuses = [JsonFile.JsonBonuses]()
var detailViewController: BonusDetailViewController? = nil

let defaults = UserDefaults.standard

let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
super.viewDidLoad()

// MARK: Search Support
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Enter two letter state to filter"
navigationItem.searchController = searchController
definesPresentationContext = true

// MARK: Settings Data Struct
struct Constants {
struct RiderData {
let riderNumToH = "riderNumToH"
let pillionNumToH = "pillionNumToH"
}
struct RallyData {
let emailDestinationToH = "emailDestinationToH"
}
}
//MARK: Load the bonuses
loadBonuses { [weak self] bonuses in
self?.bonuses = bonuses ?? []
DispatchQueue.main.async {
self?.tableView.reloadData()
}
print("loadBonuses called")
}
}
// MARK: - Table View Configuration
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
print("Showing \(filteredBonuses.count) Filtered Results")
return filteredBonuses.count
}

print("Found \(bonuses.count) rows in section.")
return bonuses.count
}

/* Disabling the swipe function until I code it to actually do something
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let clearAction = UIContextualAction(style: .normal, title: "Clear Data") { (contextAction: UIContextualAction, sourceView: UIView, completionHandler: (Bool) -> Void) in
print("Clear Action Tapped")
completionHandler(true)
}

clearAction.backgroundColor = .blue
let swipeConfig = UISwipeActionsConfiguration(actions: [clearAction])
return swipeConfig
}
*/

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "BonusListViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? BonusListViewCell else {
fatalError("The dequeued cell is not an instance of BonusListViewCell.")
}
let bonus = bonuses[indexPath.row]
let bonusSet: JsonFile.JsonBonuses
if isFiltering() {
bonusSet = filteredBonuses[indexPath.row]
} else {
bonusSet = bonus
}

let urlString = "http://tourofhonor.com/appimages/"+(bonus.imageName)
let url = URL(string: urlString)
cell.primaryImage.downloadedFrom(url: url!)
cell.nameLabel.text = bonus.name.capitalized
cell.bonusCodeLabel.text = bonus.bonusCode.localizedUppercase
cell.categoryLabel.text = bonus.category
cell.valueLabel.text = "\(bonus.value)"
cell.cityLabel.text = "\(bonus.city.capitalized),"
cell.stateLabel.text = bonus.state.localizedUppercase

return cell
}

// MARK: Functions
// MARK: - Fetch JSON from ToH webserver

func downloadJSON(completed: @escaping ([JsonFile.JsonBonuses]?) -> ()) {
let url = URL(string: "http://tourofhonor.com/BonusData.json")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error == nil, let data = data {
do {
let posts = try JSONDecoder().decode(JsonFile.self, from: data)
completed(posts.bonuses)
} catch {
print("JSON Download Failed")
}
} else {
print("downloadJSON completed")
completed(nil)
}
}.resume()
}

func saveBonuses(_ bonuses: [JsonFile.JsonBonuses], to url: URL) {
try? FileManager.default.removeItem(at: url)
do {
let data = try JSONEncoder().encode(bonuses)
try data.write(to: url)
print("saveBonuses successful")
} catch {
print("Error saving bonuses to file:", error)
}
}

func loadBonusesFromFile(_ url: URL) -> [JsonFile.JsonBonuses]? {
do {
let data = try Data(contentsOf: url)
let bonuses = try JSONDecoder().decode([JsonFile.JsonBonuses].self, from: data)
print("loadBonusesFromFile successful")
return bonuses
} catch {
print("Error loading bonuses from file:", error)
return nil
}
}

func loadBonuses(completion: @escaping ([JsonFile.JsonBonuses]?) -> Void) {
let localBonusesURL = try! FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("Bonuses.json")
downloadJSON { bonuses in
if let bonuses = bonuses {
completion(bonuses)
self.saveBonuses(bonuses, to: localBonusesURL)
} else {
completion(self.loadBonusesFromFile(localBonusesURL))
}
}
}

func searchBarIsEmpty() -> Bool {
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
}

func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredBonuses = bonuses.filter({( bonus: JsonFile.JsonBonuses) -> Bool in
return bonus.state.lowercased().contains(searchText.lowercased())
})
tableView.reloadData()
}

func isFiltering() -> Bool {
return searchController.isActive && !searchBarIsEmpty()
}

// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? BonusDetailViewController {
destination.bonus = bonuses[(tableView.indexPathForSelectedRow?.row)!]
}
}
}

extension BonusListViewController: UISearchResultsUpdating {
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}

这是 JsonFile.swift:

import Foundation

struct JsonFile: Codable {
struct Meta: Codable {
let fileName: String
let version: String
}
struct JsonBonuses: Codable {
let bonusCode: String
let category: String
let name: String
let value: Int
let city: String
let state: String
let flavor: String
let imageName: String
}
let meta: Meta
let bonuses: [JsonBonuses]
}

编辑:JSON 本身可以在 http://www.tourofhonor.com/BonusData.json 找到

此外,在显示 let bonusSet: JsonFile.JsonBonuses 的行(在 cellForRowAt 下),我收​​到一条警告,显示“Immutable value bonusSet was never使用过;考虑删除它”,即使我在下一行中使用了它。

最佳答案

我想问题出在您的 cellForRow 方法中,您应该使用 bonusSet 而不是 bonus 来分配值。因为您正在初始化 bonus dara 结构的值,该结构应该来自 bonusSet。

尝试将 cellForRow 更改为:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "BonusListViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? BonusListViewCell else {
fatalError("The dequeued cell is not an instance of BonusListViewCell.")
}
let bonus = bonuses[indexPath.row]
let bonusSet: JsonFile.JsonBonuses
if isFiltering() {
bonusSet = filteredBonuses[indexPath.row]
} else {
bonusSet = bonus
}

//CHANGE IS REQUIRED HERE: REPLACE THE bonus WITH bonusSet :
let urlString = "http://tourofhonor.com/appimages/"+(bonusSet.imageName)
let url = URL(string: urlString)
cell.primaryImage.downloadedFrom(url: url!)
cell.nameLabel.text = bonusSet.name.capitalized
cell.bonusCodeLabel.text = bonusSet.bonusCode.localizedUppercase
cell.categoryLabel.text = bonusSet.category
cell.valueLabel.text = "\(bonusSet.value)"
cell.cityLabel.text = "\(bonusSet.city.capitalized),"
cell.stateLabel.text = bonusSet.state.localizedUppercase

return cell
}

关于ios - UISearchBar 似乎返回正确的计数,但不是正确的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51204452/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com