Swift TableView 单元格无法显示来自 API 的数据
Swift TableView Cell Unable to Display the data from API
我在 table 视图单元格中创建了四个标签以从 Api 获取数据。 link 是 https://coinmap.org/api/v1/venues/ 。我有两个 swift 文件,一个用于定义 tabelview 属性,另一个用于 Label with cell 。当我 运行 应用程序显示 table 视图单元格但不显示带有标签的数据时。这是模型。
// MARK: - Welcome
struct Coin: Codable {
let venues: [Venue]
}
// MARK: - Venue
struct Venue: Codable {
let id: Int
let lat, lon: Double
let category, name: String
let createdOn: Int
let geolocationDegrees: String
enum CodingKeys: String, CodingKey {
case id, lat, lon, category, name
case createdOn = "created_on"
case geolocationDegrees = "geolocation_degrees"
}
}
这里是网络管理员。
class NetworkManager {
func getCoins(from url: String, completion: @escaping (Result<Coin, NetworkError>) -> Void ) {
guard let url = URL(string: url) else {
completion(.failure(.badURL))
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
completion(.failure(.other(error)))
return
}
if let data = data {
//decode
do {
let response = try JSONDecoder().decode(Coin.self, from: data)
completion(.success(response))
} catch let error {
completion(.failure(.other(error)))
}
}
}
.resume()
}
}
主持人来了
class VenuePresenter : VanueProtocol{
// creating instance of the class
private let view : VanueViewProtocol
private let networkManager: NetworkManager
private var vanues = [Venue]()
var rows: Int{
return vanues.count
}
// initilanize the class
init(view:VanueViewProtocol , networkmanager:NetworkManager = NetworkManager()){
self.view = view
self.networkManager = networkmanager
}
func getVanue(){
let url = "https://coinmap.org/api/v1/venues/"
networkManager.getCoins(from: url) { result in
switch result {
case.success(let respone):
self.vanues = respone.venues
DispatchQueue.main.async {
self.view.resfreshTableView()
}
case .failure(let error):
DispatchQueue.main.async {
self.view.displayError(error.errorDescription ?? "")
print(error)
}
}
}
}
func getId(by row: Int) -> Int {
return vanues[row].id
}
func getLat(by row: Int) -> Double {
return vanues[row].lat
}
func getCreated(by row: Int) -> Int {
return vanues[row].createdOn
}
func getLon(by row: Int) -> Double? {
return vanues[row].lon
}
}
这是视图控制器。
class ViewController: UIViewController{
private var presenter : VenuePresenter!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
setUpUI()
presenter = VenuePresenter(view: self)
presenter.getVanue()
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "DisplayView1")
// Do any additional setup after loading the view.
}
private func setUpUI() {
tableView.dataSource = self
tableView.delegate = self
}
}
extension ViewController : VanueViewProtocol{
func resfreshTableView() {
tableView.reloadData()
}
func displayError(_ message: String) {
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
let doneButton = UIAlertAction(title: "Done", style: .default, handler: nil)
alert.addAction(doneButton)
present(alert, animated: true, completion: nil)
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
presenter.rows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: DisplayView.identifier, for: indexPath) as? DisplayView
else { return UITableViewCell() }
let row = indexPath.row
let id = presenter.getId(by: row)
let lat = presenter.getLat(by: row)
guard let lon = presenter.getLon(by: row) else { return UITableViewCell() }
let createdOn = presenter.getCreated(by: row)
cell.configureCell(id: id, lat: lat, lon: lon, createdOn: createdOn)
return cell
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
这是显示视图 swift .
class DisplayView: UITableViewCell{
static let identifier = "DisplayView1"
@IBOutlet weak var label1: UILabel!
@IBOutlet weak var label2: UILabel!
@IBOutlet weak var label3: UILabel!
@IBOutlet weak var label4: UILabel!
func configureCell(id: Int ,lat : Double , lon : Double , createdOn: Int){
label1.text = String(id)
label2.text = String(lat)
label3.text = String(lon)
label4.text = String(createdOn)
}
}
这里的截图是空的,没有显示数据。
您正在注册通用单元:
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "DisplayView1")
您需要注册您的自定义手机:
self.tableView.register(DisplayView.self, forCellReuseIdentifier: DisplayView.identifier)
我在 table 视图单元格中创建了四个标签以从 Api 获取数据。 link 是 https://coinmap.org/api/v1/venues/ 。我有两个 swift 文件,一个用于定义 tabelview 属性,另一个用于 Label with cell 。当我 运行 应用程序显示 table 视图单元格但不显示带有标签的数据时。这是模型。
// MARK: - Welcome
struct Coin: Codable {
let venues: [Venue]
}
// MARK: - Venue
struct Venue: Codable {
let id: Int
let lat, lon: Double
let category, name: String
let createdOn: Int
let geolocationDegrees: String
enum CodingKeys: String, CodingKey {
case id, lat, lon, category, name
case createdOn = "created_on"
case geolocationDegrees = "geolocation_degrees"
}
}
这里是网络管理员。
class NetworkManager {
func getCoins(from url: String, completion: @escaping (Result<Coin, NetworkError>) -> Void ) {
guard let url = URL(string: url) else {
completion(.failure(.badURL))
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
completion(.failure(.other(error)))
return
}
if let data = data {
//decode
do {
let response = try JSONDecoder().decode(Coin.self, from: data)
completion(.success(response))
} catch let error {
completion(.failure(.other(error)))
}
}
}
.resume()
}
}
主持人来了
class VenuePresenter : VanueProtocol{
// creating instance of the class
private let view : VanueViewProtocol
private let networkManager: NetworkManager
private var vanues = [Venue]()
var rows: Int{
return vanues.count
}
// initilanize the class
init(view:VanueViewProtocol , networkmanager:NetworkManager = NetworkManager()){
self.view = view
self.networkManager = networkmanager
}
func getVanue(){
let url = "https://coinmap.org/api/v1/venues/"
networkManager.getCoins(from: url) { result in
switch result {
case.success(let respone):
self.vanues = respone.venues
DispatchQueue.main.async {
self.view.resfreshTableView()
}
case .failure(let error):
DispatchQueue.main.async {
self.view.displayError(error.errorDescription ?? "")
print(error)
}
}
}
}
func getId(by row: Int) -> Int {
return vanues[row].id
}
func getLat(by row: Int) -> Double {
return vanues[row].lat
}
func getCreated(by row: Int) -> Int {
return vanues[row].createdOn
}
func getLon(by row: Int) -> Double? {
return vanues[row].lon
}
}
这是视图控制器。
class ViewController: UIViewController{
private var presenter : VenuePresenter!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
setUpUI()
presenter = VenuePresenter(view: self)
presenter.getVanue()
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "DisplayView1")
// Do any additional setup after loading the view.
}
private func setUpUI() {
tableView.dataSource = self
tableView.delegate = self
}
}
extension ViewController : VanueViewProtocol{
func resfreshTableView() {
tableView.reloadData()
}
func displayError(_ message: String) {
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
let doneButton = UIAlertAction(title: "Done", style: .default, handler: nil)
alert.addAction(doneButton)
present(alert, animated: true, completion: nil)
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
presenter.rows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: DisplayView.identifier, for: indexPath) as? DisplayView
else { return UITableViewCell() }
let row = indexPath.row
let id = presenter.getId(by: row)
let lat = presenter.getLat(by: row)
guard let lon = presenter.getLon(by: row) else { return UITableViewCell() }
let createdOn = presenter.getCreated(by: row)
cell.configureCell(id: id, lat: lat, lon: lon, createdOn: createdOn)
return cell
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
这是显示视图 swift .
class DisplayView: UITableViewCell{
static let identifier = "DisplayView1"
@IBOutlet weak var label1: UILabel!
@IBOutlet weak var label2: UILabel!
@IBOutlet weak var label3: UILabel!
@IBOutlet weak var label4: UILabel!
func configureCell(id: Int ,lat : Double , lon : Double , createdOn: Int){
label1.text = String(id)
label2.text = String(lat)
label3.text = String(lon)
label4.text = String(createdOn)
}
}
这里的截图是空的,没有显示数据。
您正在注册通用单元:
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "DisplayView1")
您需要注册您的自定义手机:
self.tableView.register(DisplayView.self, forCellReuseIdentifier: DisplayView.identifier)