在 tableView swift4 中搜索 JSON 条数据
Search JSON data in tableView swift4
我试图在 tableView
中显示 jsondata
并从 searchBar
中搜索 country
但在 [=19] 中显示 error
=]函数。
我希望用户在 searchBar
中输入三个词,然后 tableView
将打开并搜索数据。
struct country : Decodable {
let name : String
let capital : String
let region : String
}
class ViewController: UIViewController,UISearchBarDelegate {
var isSearch : Bool = false
var countries = [country]()
var arrFilter:[String] = []
@IBOutlet weak var tableview: UITableView!
@IBOutlet weak var searchbar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
tableview.dataSource = self
tableview.delegate = self
searchbar.delegate = self
let jsonurl = "https://restcountries.eu/rest/v2/all"
let url = URL(string: jsonurl)
URLSession.shared.dataTask(with: url!) { (data, response, error) in
do{
self.countries = try JSONDecoder().decode([country].self, from: data!)
}
catch{
print("Error")
}
DispatchQueue.main.async {
self.tableview.reloadData()
}
}.resume()
}
这部分显示错误。
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.characters.count == 0 {
isSearch = false;
self.tableview.reloadData()
} else {
arrFilter = countries.filter({ (text) -> Bool in
let tmp: NSString = text
let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
return range.location != NSNotFound
})
if(arrFilter.count == 0){
isSearch = false;
} else {
isSearch = true;
}
self.tableview.reloadData()
}
}
}
我的 table 查看部分
extension ViewController : UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(isSearch){
return arrFilter.count
}
else{
return countries.coun
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if(isSearch){
cell.textLabel?.text = arrFilter[indexPath.row]
}else{
cell.textLabel?.text = countries[indexPath.row].name.capitalized
}
return cell
}
}
您正在获取数组的国家/地区对象作为字符串,所以发生了这样的错误..
请按以下步骤
var arrFilter:[country] = [country]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if(isSearch){
cell.textLabel?.text = arrFilter[indexPath.row].name.capitalized
}else{
cell.textLabel?.text = countries[indexPath.row].name.capitalized
}
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.characters.count == 0 {
isSearch = false;
self.tableview.reloadData()
} else {
arrFilter = countries.filter({ (country) -> Bool in
let tmp: NSString = NSString.init(string: country.name)
let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive)
return range.location != NSNotFound
})
if(arrFilter.count == 0){
isSearch = false;
} else {
isSearch = true;
}
self.tableview.reloadData()
}
}
首先,您不能将值类型 [Country] 分配给 [String]。例如,当时分配 arrFilter 时 country.filter 总是 return country 类型值不是字符串类型。
使用下面的代码来帮助你,
var countries = [country]()
var arrFilter:[country] = [country]()
在 viewdidLoad 里面
override func viewDidLoad() {
self.countries.append(country(name: "India", capital: "New Delhi", region: "Asia"))
self.countries.append(country(name: "Indonesia", capital: "Jakarta", region: "region"))
self.countries.append(country(name: "Australia", capital: "Canberra", region: "Austrialia"))
// Do any additional setup after loading the view.
}
和
self.arrFilter = self.countries.filter({ (country) -> Bool in
let temp : NSString = country.name as NSString //or you can use country.capital or country.region
let range = temp.range(of: "ind", options: .caseInsensitive)
print(range.location)
print(range.length)
print(temp)
return range.location != NSNotFound
})
谢谢
- 首先不要在Swift和
Foundation
rangeOfString
API中使用NSString
,使用原生 String
和原生 range(of
.
- 其次,永远不要使用
.count == 0
检查空字符串和空数组。有isEmpty
.
- 第三,请以大写字母开头的结构和 类 命名。
struct Country ...
.
发生错误是因为您正在过滤 Country
个实例,而实际上您正在寻找它的 name
或它的 region
.
这是您代码的纯 Swift 版本
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
isSearch = false
} else {
arrFilter = countries.filter( [=10=].name.range(of: searchText, options: .caseInsensitive) != nil }
isSearch = !arrFilter.isEmpty
}
self.tableview.reloadData()
}
如果要筛选 name
和 region
,请写
arrFilter = countries.filter( [=11=].name.range(of: searchText, options: .caseInsensitive) != nil
|| [=11=].region.range(of: searchText, options: .caseInsensitive) != nil }
使用此语法声明 arrFilter
var arrFilter = [Country]()
并在cellForRow
中写入
let dataArray = isSearch ? arrFilter : countries
cell.textLabel?.text = dataArray[indexPath.row].name.capitalized
我试图在 tableView
中显示 jsondata
并从 searchBar
中搜索 country
但在 [=19] 中显示 error
=]函数。
我希望用户在 searchBar
中输入三个词,然后 tableView
将打开并搜索数据。
struct country : Decodable {
let name : String
let capital : String
let region : String
}
class ViewController: UIViewController,UISearchBarDelegate {
var isSearch : Bool = false
var countries = [country]()
var arrFilter:[String] = []
@IBOutlet weak var tableview: UITableView!
@IBOutlet weak var searchbar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
tableview.dataSource = self
tableview.delegate = self
searchbar.delegate = self
let jsonurl = "https://restcountries.eu/rest/v2/all"
let url = URL(string: jsonurl)
URLSession.shared.dataTask(with: url!) { (data, response, error) in
do{
self.countries = try JSONDecoder().decode([country].self, from: data!)
}
catch{
print("Error")
}
DispatchQueue.main.async {
self.tableview.reloadData()
}
}.resume()
}
这部分显示错误。
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.characters.count == 0 {
isSearch = false;
self.tableview.reloadData()
} else {
arrFilter = countries.filter({ (text) -> Bool in
let tmp: NSString = text
let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
return range.location != NSNotFound
})
if(arrFilter.count == 0){
isSearch = false;
} else {
isSearch = true;
}
self.tableview.reloadData()
}
}
}
我的 table 查看部分
extension ViewController : UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(isSearch){
return arrFilter.count
}
else{
return countries.coun
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if(isSearch){
cell.textLabel?.text = arrFilter[indexPath.row]
}else{
cell.textLabel?.text = countries[indexPath.row].name.capitalized
}
return cell
}
}
您正在获取数组的国家/地区对象作为字符串,所以发生了这样的错误.. 请按以下步骤
var arrFilter:[country] = [country]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if(isSearch){
cell.textLabel?.text = arrFilter[indexPath.row].name.capitalized
}else{
cell.textLabel?.text = countries[indexPath.row].name.capitalized
}
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.characters.count == 0 {
isSearch = false;
self.tableview.reloadData()
} else {
arrFilter = countries.filter({ (country) -> Bool in
let tmp: NSString = NSString.init(string: country.name)
let range = tmp.range(of: searchText, options: NSString.CompareOptions.caseInsensitive)
return range.location != NSNotFound
})
if(arrFilter.count == 0){
isSearch = false;
} else {
isSearch = true;
}
self.tableview.reloadData()
}
}
首先,您不能将值类型 [Country] 分配给 [String]。例如,当时分配 arrFilter 时 country.filter 总是 return country 类型值不是字符串类型。
使用下面的代码来帮助你,
var countries = [country]()
var arrFilter:[country] = [country]()
在 viewdidLoad 里面
override func viewDidLoad() {
self.countries.append(country(name: "India", capital: "New Delhi", region: "Asia"))
self.countries.append(country(name: "Indonesia", capital: "Jakarta", region: "region"))
self.countries.append(country(name: "Australia", capital: "Canberra", region: "Austrialia"))
// Do any additional setup after loading the view.
}
和
self.arrFilter = self.countries.filter({ (country) -> Bool in
let temp : NSString = country.name as NSString //or you can use country.capital or country.region
let range = temp.range(of: "ind", options: .caseInsensitive)
print(range.location)
print(range.length)
print(temp)
return range.location != NSNotFound
})
谢谢
- 首先不要在Swift和
Foundation
rangeOfString
API中使用NSString
,使用原生String
和原生range(of
. - 其次,永远不要使用
.count == 0
检查空字符串和空数组。有isEmpty
. - 第三,请以大写字母开头的结构和 类 命名。
struct Country ...
.
发生错误是因为您正在过滤 Country
个实例,而实际上您正在寻找它的 name
或它的 region
.
这是您代码的纯 Swift 版本
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
isSearch = false
} else {
arrFilter = countries.filter( [=10=].name.range(of: searchText, options: .caseInsensitive) != nil }
isSearch = !arrFilter.isEmpty
}
self.tableview.reloadData()
}
如果要筛选 name
和 region
,请写
arrFilter = countries.filter( [=11=].name.range(of: searchText, options: .caseInsensitive) != nil
|| [=11=].region.range(of: searchText, options: .caseInsensitive) != nil }
使用此语法声明 arrFilter
var arrFilter = [Country]()
并在cellForRow
中写入
let dataArray = isSearch ? arrFilter : countries
cell.textLabel?.text = dataArray[indexPath.row].name.capitalized