ios - 为什么从 json 响应显示在 tableView 无序列表值 swift 5
问题描述
在此处输入图像描述导入 UIKit
类 MyCircleViewPresenter:BaseViewPresenter {
typealias V = MyCircleViewDelegate
var mView: V?
func getMyCircle(url: String){
mView?.onNetworkCallStarted("please_wait".localized())
AlamofireService.getSession()
.request(url, method: .get).validate()
.responseJSON { (response) in
self.mView?.onNetworkCallEnded()
switch(response.result){
case .success(_):
guard let decodedObj = response.decode(objectType: MyCircleResponse.self) else {
self.mView?.myCircleDidReceived(response: nil)
return
}
self.mView?.myCircleDidReceived(response: decodedObj)
break
case .failure(let error):
self.mView?.handleError(httpSatusCode: response.response?.statusCode, errorData: response.data, error: error)
break
}
}
}
}
// // MyCircleViewController.swift
导入 UIKit
结构 MyCircleSection {
let number: String
let recharges: [SingeRecharge]
var isOpened: Bool = false
struct SingeRecharge {
let amount: String
let rechargeType: Int
let create_at: String
}
}
类 MyCircleViewController: BaseViewController {
// Out let >>>>>
@IBOutlet weak var card_current_month: CardView!
@IBOutlet weak var card_last_3o_days: CardView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var lb_my_circle_total: RegularLabel!
var sections = [MyCircleSection]()
var mPresenter = MyCircleViewPresenter()
var historyType = Constants.HistoryType.CURRENT_MONTH
override func onViewDidLoaded() {
mPresenter.setViewDelegate(mView: self)
// Set Up table View
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.rowHeight = 62
// Swipe
let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
swipeLeft.direction = .left
self.view!.addGestureRecognizer(swipeLeft)
setupClickListener()
card_current_month.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
card_current_month.shadowColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
card_last_3o_days.shadowColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
}
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(menuDidTapped), name: .MENU_DID_TAPPED, object: nil)
if(historyType == Constants.HistoryType.CURRENT_MONTH){ // Curent Month
card_current_month.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
mPresenter.getMyCircle(url: APIs.MY_CIRCLE + "/\(historyType)")
}else{ // Last 30 days
card_current_month.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
mPresenter.getMyCircle(url: APIs.MY_CIRCLE + "/\(historyType)")
}
lb_my_circle_total.text = "..."
tableView.isHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: .MENU_DID_TAPPED, object: nil)
}
@objc func menuDidTapped(_ notification: NSNotification){
guard let menuType = notification.object as? MenuType else {
return
}
print("Menu Type: Reward >>> \(menuType)")
switch menuType {
case .PROFILE:
performSegue(withIdentifier: ProfileViewController.className, sender: self)
break
case .REFER_SC_APP:
AppUtils.shared.referThisApp(fromVc: self)
break
case .TRANSACTION_AND_STATEMENT:
performSegue(withIdentifier: TransactionViewController.className, sender: self)
break
case .FAQ:
performSegue(withIdentifier: FaqViewController.className, sender: self)
break
case .SUPPORT:
performSegue(withIdentifier: SupportViewController.className, sender: self)
break
case .SETTINGS:
performSegue(withIdentifier: SettingsViewController.className, sender: self)
break
case .LOGOUT:
showLogoutDialog()
break
}
}
func setupClickListener(){
card_current_month.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tabClickListener(_:))))
card_last_3o_days.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tabClickListener(_:))))
}
@objc func tabClickListener(_ gesture: UIGestureRecognizer){
guard let tag = gesture.view?.tag else { return }
if(tag == 1){ // Curent Month
if(historyType != Constants.HistoryType.CURRENT_MONTH){
historyType = Constants.HistoryType.CURRENT_MONTH
lb_my_circle_total.text = "..."
tableView.isHidden = true
card_current_month.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
mPresenter.getMyCircle(url: APIs.MY_CIRCLE + "/\(Constants.HistoryType.CURRENT_MONTH)")
}
}else{ // Last 30 days
if(historyType != Constants.HistoryType.LAST_30_DAYS){
historyType = Constants.HistoryType.LAST_30_DAYS
lb_my_circle_total.text = "..."
tableView.isHidden = true
card_current_month.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
mPresenter.getMyCircle(url: APIs.MY_CIRCLE + "/\(Constants.HistoryType.LAST_30_DAYS)")
}
}
}
@objc func handleGesture(gesture: UISwipeGestureRecognizer) -> Void {
if gesture.direction == UISwipeGestureRecognizer.Direction.left {
NotificationCenter.default.post(name: .USER_DID_SWIPE_TO_LEFT, object: nil)
}
}
}
扩展 MyCircleViewController: MyCircleViewDelegate {
func myCircleDidReceived(response: MyCircleResponse?) {
if(response == nil){
lb_my_circle_total.text = "0"
showErrorDialog(title: "No data found!", msg: nil, titleFullRed: true)
}else{
lb_my_circle_total.text = "\(response!.data.count)"
// Format Data for Table View >>>
if (!sections.isEmpty) {sections.removeAll()}
for (number , recharges) in response!.data {
var rechargeHistories = [MyCircleSection.SingeRecharge]()
for singleRecharge in recharges {
rechargeHistories.append(MyCircleSection.SingeRecharge(amount: singleRecharge.amount, rechargeType : singleRecharge.rechargeType, create_at: singleRecharge.createdAt))
}
sections.append(MyCircleSection(number: number, recharges: rechargeHistories))
}
// Reload Table view data >>>
self.tableView.reloadData()
self.tableView.isHidden = false
}
}
}
//// 表视图委托 >>> 扩展 MyCircleViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let section = sections[section]
return section.isOpened ? section.recharges.count + 1 : 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(indexPath.row == 0){
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCircleHeaderCell.className) as? MyCircleHeaderCell else {
return UITableViewCell()
}
let section = sections[indexPath.section]
cell.lb_circle_number.text = section.recharges.isEmpty ? section.number : section.number + " (\(section.recharges.count))"
cell.img_arrow.image = section.isOpened ? UIImage(named: "ic-arrow-up") : UIImage(named: "ic-down-arrow")
return cell
}else{
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCircleRowCell.className) as? MyCircleRowCell else {
return UITableViewCell()
}
let data = sections[indexPath.section].recharges[indexPath.row - 1]
cell.lb_amount.text = Constants.TAKA_UNICODE + "\(data.amount)"
let formattedDateTime = DateUtils.shared.convertUTCtimeToLocale(dateToFormat: data.create_at)
cell.lb_date.text = formattedDateTime.0
cell.lb_time.text = formattedDateTime.1
switch "\(data.rechargeType)" {
case Constants.RechargeType.EASY_LOAD:
cell.lb_type.text = "Easyload"
case Constants.RechargeType.BUNDLE:
cell.lb_type.text = "Bundle"
case Constants.RechargeType.INTERNET:
cell.lb_type.text = "Internet"
case Constants.RechargeType.VOICE:
cell.lb_type.text = "Voice"
case Constants.RechargeType.VAS:
cell.lb_type.text = "Vas"
default:
cell.lb_type.text = ""
break
}
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if(indexPath.row == 0){
sections[indexPath.section].isOpened = !sections[indexPath.section].isOpened
tableView.reloadSections([indexPath.section], with: .none)
}
}
}
// Qeustion Cell >>>> class MyCircleHeaderCell: UITableViewCell{
@IBOutlet weak var lb_circle_number : RegularLabel!
@IBOutlet weak var img_arrow: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
self.selectionStyle = .none
}
}
// Answer Cell >>> class MyCircleRowCell: UITableViewCell {
@IBOutlet weak var lb_date : PreRegularLight!
@IBOutlet weak var lb_time : PreRegularLight!
@IBOutlet weak var lb_amount: PreRegularBoldLabel!
@IBOutlet weak var lb_type: PreRegularLight!
override func awakeFromNib() {
super.awakeFromNib()
self.selectionStyle = .none
}
}
解决方案
JSON 响应永远不会以某种方式排序。它总是以不同的顺序出现,并被如此解码。我建议您自己按日期或其他方式对数组进行排序,以获得一致的对象顺序。
推荐阅读
- linux - chmod 仅在当前目录中的文件,但不是子目录和主目录
- javascript - my-component.js:24 未捕获的类型错误:window.open 不是函数
- azure-devops - 在 Azure Devops 管道中通过 VSTest 适配器运行超过 21 个测试时出现 RPC 错误
- python - 如何在不使用数据透视表的情况下创建数据框以加快执行速度?
- django - docker django:为什么要将上下文复制到 docker 映像中,如果我们通过在 docker compose 中安装一些东西来覆盖它
- php - 错误 session_start():当文件头已经发送到 PHP 中时无法启动会话?
- javascript - 如果所有字段均已填写且电子邮件字段有效,则显示表单的下一步
- vue.js - 页面重新加载后 Vuetify DarkMode 颜色错误
- python - MATLAB python绑定:'cell'类型的输入参数的未定义函数'isfinite'
- arm - 如何从 SoC 直接写入 FPGA 外设?