在 tableView Swift 中表示解析 JSON 的结果
Represent result of parsing JSON in tableView Swift
我从 Paul Hudson 的“Swift 的 100 天”开始学习 swift,我需要您的建议。
我正在尝试使用国家/地区的信息(首都、语言、货币等)制作应用程序,并坚持尝试在 tableView 中表示我的 JSON 解析结果。
这是我从 https://restcountries.com/v3.1/all
解析国家信息的结构
struct Country: Codable {
let name: Name
let cca2: String
let capital: [String]?
let population: Int
let currencies: [String: Currency]?
}
struct Name: Codable {
let common: String
let official: String
}
struct Currency: Codable {
let name: String?
let symbol: String?
}
我有货币方面的问题。我不明白如何在 tableView 中正确地表示它们。这是我的代码 ViewController:
import UIKit
class ViewController: UITableViewController {
var countries = [Country] ()
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "https://restcountries.com/v3.1/all"
if let url = URL(string: urlString) {
if let data = try? Data(contentsOf: url) {
parse(json: data)
return
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
countries.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Country", for: indexPath)
let country = countries[indexPath.row]
cell.textLabel?.text = country.name.common
cell.imageView?.image = UIImage(named: country.cca2.lowercased())
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController {
vc.country = countries[indexPath.row]
present(vc, animated: true)
}
}
func parse(json: Data) {
let decoder = JSONDecoder()
do {
let jsonCountries = try decoder.decode([Country].self, from: json)
countries = jsonCountries
}
catch let error {
print(error)
}
}
}
这是我的详情代码ViewController:
import UIKit
class DetailViewController: UITableViewController {
var country: Country!
let flag = "Flag"
let general = "General"
let currency = "Currency"
var currencyName = ""
var currencySymbol = ""
lazy var sectionTitles = [flag, general, currency]
lazy var currencies = country.currencies?.values
override func viewDidLoad() {
super.viewDidLoad()
title = country.name.common
getCurrencyName()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return sectionTitles.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionTitles[section]
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch sectionTitles[section] {
case flag:
return 1
case general:
return 4
case currency:
// How make to return proper number's of rows??
return 2
default:
return 0
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch sectionTitles[indexPath.section] {
case flag:
let cell = tableView.dequeueReusableCell(withIdentifier: "Flag", for: indexPath)
if let cell = cell as? FlagCell {
cell.flagImageView.image = UIImage(named: country.cca2.lowercased())
}
return cell
case general:
let cell = tableView.dequeueReusableCell(withIdentifier: "Text", for: indexPath)
cell.textLabel?.numberOfLines = 0
switch indexPath.row {
case 0:
cell.textLabel?.text = "Common country name: \(country.name.common)"
case 1:
cell.textLabel?.text = "Official country name: \(country.name.official)"
case 2:
cell.textLabel?.text = "Capital: \(country.capital?[0] ?? "Unknown")"
case 3:
cell.textLabel?.text = "Population: \(country.population) people"
default:
return cell
}
return cell
case currency:
let cell = tableView.dequeueReusableCell(withIdentifier: "Text", for: indexPath)
cell.textLabel?.numberOfLines = 0
switch indexPath.row {
case 0:
// How to represent each currency of country?
cell.textLabel?.text = "Currency name: \(currencyName)"
case 1:
cell.textLabel?.text = "Currency symbol: \(currencySymbol)"
default:
return cell
}
return cell
default:
break
}
return UITableViewCell ()
}
func getCurrencyName () {
for currency in currencies! {
currencyName = currency.name ?? ""
currencySymbol = currency.symbol ?? ""
}
}
}
现在我了解如何表示每个国家/地区的一种货币,但是如何在不同的行中表示每个国家/地区的所有货币?
抱歉我的英语不是我的母语:)
您可以通过此访问每个国家/地区的货币数量,并在 numberOfRowsInSection
方法中使用它来 return 足够的货币行数:
country.currencies.count
剩下的就是使用 indexPath 的部分和行值填充 cellForRowAt
方法中的单元格。您应该遍历所选国家/地区的货币字典,并在一行中显示字典中的每个键和值对。
您可以像这样进行迭代:
for (key, value) in dict {
// Use key and value here
}
我建议获取货币的排序列表。例如,对于给定的 Country
:
let currencies = country.currencies?.sorted { [=10=].0 < .0 }
获取计数:
let count = currencies?.count ?? 0
要获取特定行的详细信息,应该是:
if let (code, currency) = currencies?[indexPath.row] {
let currencyCode = code
let currencyName = currency.name
let currencySymbol = currency.symbol
}
我从 Paul Hudson 的“Swift 的 100 天”开始学习 swift,我需要您的建议。 我正在尝试使用国家/地区的信息(首都、语言、货币等)制作应用程序,并坚持尝试在 tableView 中表示我的 JSON 解析结果。 这是我从 https://restcountries.com/v3.1/all
解析国家信息的结构struct Country: Codable {
let name: Name
let cca2: String
let capital: [String]?
let population: Int
let currencies: [String: Currency]?
}
struct Name: Codable {
let common: String
let official: String
}
struct Currency: Codable {
let name: String?
let symbol: String?
}
我有货币方面的问题。我不明白如何在 tableView 中正确地表示它们。这是我的代码 ViewController:
import UIKit
class ViewController: UITableViewController {
var countries = [Country] ()
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "https://restcountries.com/v3.1/all"
if let url = URL(string: urlString) {
if let data = try? Data(contentsOf: url) {
parse(json: data)
return
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
countries.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Country", for: indexPath)
let country = countries[indexPath.row]
cell.textLabel?.text = country.name.common
cell.imageView?.image = UIImage(named: country.cca2.lowercased())
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController {
vc.country = countries[indexPath.row]
present(vc, animated: true)
}
}
func parse(json: Data) {
let decoder = JSONDecoder()
do {
let jsonCountries = try decoder.decode([Country].self, from: json)
countries = jsonCountries
}
catch let error {
print(error)
}
}
}
这是我的详情代码ViewController:
import UIKit
class DetailViewController: UITableViewController {
var country: Country!
let flag = "Flag"
let general = "General"
let currency = "Currency"
var currencyName = ""
var currencySymbol = ""
lazy var sectionTitles = [flag, general, currency]
lazy var currencies = country.currencies?.values
override func viewDidLoad() {
super.viewDidLoad()
title = country.name.common
getCurrencyName()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return sectionTitles.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionTitles[section]
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch sectionTitles[section] {
case flag:
return 1
case general:
return 4
case currency:
// How make to return proper number's of rows??
return 2
default:
return 0
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch sectionTitles[indexPath.section] {
case flag:
let cell = tableView.dequeueReusableCell(withIdentifier: "Flag", for: indexPath)
if let cell = cell as? FlagCell {
cell.flagImageView.image = UIImage(named: country.cca2.lowercased())
}
return cell
case general:
let cell = tableView.dequeueReusableCell(withIdentifier: "Text", for: indexPath)
cell.textLabel?.numberOfLines = 0
switch indexPath.row {
case 0:
cell.textLabel?.text = "Common country name: \(country.name.common)"
case 1:
cell.textLabel?.text = "Official country name: \(country.name.official)"
case 2:
cell.textLabel?.text = "Capital: \(country.capital?[0] ?? "Unknown")"
case 3:
cell.textLabel?.text = "Population: \(country.population) people"
default:
return cell
}
return cell
case currency:
let cell = tableView.dequeueReusableCell(withIdentifier: "Text", for: indexPath)
cell.textLabel?.numberOfLines = 0
switch indexPath.row {
case 0:
// How to represent each currency of country?
cell.textLabel?.text = "Currency name: \(currencyName)"
case 1:
cell.textLabel?.text = "Currency symbol: \(currencySymbol)"
default:
return cell
}
return cell
default:
break
}
return UITableViewCell ()
}
func getCurrencyName () {
for currency in currencies! {
currencyName = currency.name ?? ""
currencySymbol = currency.symbol ?? ""
}
}
}
现在我了解如何表示每个国家/地区的一种货币,但是如何在不同的行中表示每个国家/地区的所有货币? 抱歉我的英语不是我的母语:)
您可以通过此访问每个国家/地区的货币数量,并在 numberOfRowsInSection
方法中使用它来 return 足够的货币行数:
country.currencies.count
剩下的就是使用 indexPath 的部分和行值填充 cellForRowAt
方法中的单元格。您应该遍历所选国家/地区的货币字典,并在一行中显示字典中的每个键和值对。
您可以像这样进行迭代:
for (key, value) in dict {
// Use key and value here
}
我建议获取货币的排序列表。例如,对于给定的 Country
:
let currencies = country.currencies?.sorted { [=10=].0 < .0 }
获取计数:
let count = currencies?.count ?? 0
要获取特定行的详细信息,应该是:
if let (code, currency) = currencies?[indexPath.row] {
let currencyCode = code
let currencyName = currency.name
let currencySymbol = currency.symbol
}