如何在Swift中根据json id(意味着indexPath应该与json id匹配)从collectionView didSelectItemAt indexPath pushViewContro

Posted

技术标签:

【中文标题】如何在Swift中根据json id(意味着indexPath应该与json id匹配)从collectionView didSelectItemAt indexPath pushViewController【英文标题】:How to pushViewController from collectionView didSelectItemAt indexPath according to json id(means indexPath should match with json id) in Swift 【发布时间】:2019-09-16 19:46:23 【问题描述】:

我的家庭 Viewcontroller 包含带有项目的 collectionView。通常,当我们单击集合视图中的任何项目时,我们可以使用 didSelectItemAt indexPath 推送到其他视图控制器。但是在这里,我从 Json 和其他 viewController 中获取每个项目图像 url 及其 id,对于每个家庭 id,我得到单独的 url,其中包含来自 Json 的其他字段。当 home id 和其他 viewcontroller id 匹配时,我需要使用 home Viewcontroller 中的 didSelectItemAt indexPath 推送到该 viewContoller。

这是我的代码:

主页 json:

"financer": [
            
                "id": "45",
                "icon": "https://emi.com/Star/images/LSPUBLICSCHOOL_icon.png",
                "tpe": "L S PUBLIC SCHOOL",

            
            
               "id": "2",
               "icon": "https://emi.com/Star/images/MC_icon.png",
               "tpe": "MC",

            
                 .
                 . 

HomeVC 代码:

import UIKit

struct JsonData 

var iconHome: String?
var typeName: String?
init(icon: String, tpe: String) 

    self.iconHome = icon
    self.typeName = tpe



class HomeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource 

@IBOutlet weak var collectionView: UICollectionView!

var itemsArray = [JsonData]()
var idArray = [String]()
override func viewDidLoad() 
    super.viewDidLoad()

    homeServiceCall()
    collectionView.delegate = self
    collectionView.dataSource = self
    let layout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 2.0, left: 2.0, bottom: 2.0, right: 2.0)
    layout.itemSize = CGSize(width: 95, height: 95)
    collectionView?.collectionViewLayout  = layout

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return itemsArray.count


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! HomeCollectionViewCell

    let aData = itemsArray[indexPath.row]
    cell.paymentLabel.text = aData.typeName

    if let url = NSURL(string: aData.iconHome ?? "") 
        if let data = NSData(contentsOf: url as URL) 
            cell.paymentImage.image = UIImage(data: data as Data)
        
    
    return cell

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 

    //let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
    let nextViewController = self.storyboard?.instantiateViewController(withIdentifier: "MakePaymentViewController") as! MakePaymentViewController
    self.navigationController?.pushViewController(nextViewController, animated: true)
    let indexPathHome = indexPath.row
    print("home collectionItem indexpath \(indexPathHome)")



//MARK:- Service-call

func homeServiceCall()

    let urlStr = "https://dev.emi.com/webservice/emi/getfinancer"
    let url = URL(string: urlStr)
    URLSession.shared.dataTask(with: url!, completionHandler: (data, response, error) in

        guard let respData = data else 
            return
        
        guard error == nil else 
            print("error")
            return
        
        do
            DispatchQueue.main.async 
                self.activityIndicator.startAnimating()
            
            let jsonObj = try JSONSerialization.jsonObject(with: respData, options: .allowFragments) as! [String: Any]
            print("the home json is \(jsonObj)")
            let financerArray = jsonObj["financer"] as! [[String: Any]]

            for financer in financerArray 

                let id = financer["id"] as! String
                let pic = financer["icon"] as? String
                let type = financer["tpe"] as! String
                self.itemsArray.append(JsonData(icon: pic ?? "", tpe: type))

            

            DispatchQueue.main.async 
                self.collectionView.reloadData()
            
        
        catch 
            print("catch error")
        
        DispatchQueue.main.async 
            self.activityIndicator.stopAnimating()
        
    ).resume()



其他VC Json:

对于来自家里的 id 2 低于 json。对于 id 45,我正在获取另一个 json。如果 home id 2 和其他 vcs id 2 匹配,则需要显示此字段如果 id 45 匹配则需要说将很快更新消息以显示。

    
    "loan_details": 
                      "id": "2",
                      "emi_amount": "1915",
                      "financer": "4",
                    

代码;

import UIKit

class MakePaymentViewController: UIViewController 

@IBOutlet weak var serviceNumTextField: UITextField!
@IBOutlet weak var serviceNumLabel: UILabel!
@IBOutlet weak var dueamountLabel: UILabel!

override func viewDidLoad() 
    super.viewDidLoad()



@IBAction func makePaymentButton(_ sender: Any) 


func makePaymentService()

    let parameters = ["assessmentNo":  Int(serviceNumTextField.text ?? ""),
                      "id":"2",
                      ] as? [String : Any]

    let url = URL(string: "https://dev.emi.com/webservice/emi/getassment_details")
    var req =  URLRequest(url: url!)
    req.httpMethod = "POST"
    req.addValue("application/json", forHTTPHeaderField: "Contet-Type")
    req.addValue("application/json", forHTTPHeaderField: "Accept")

    guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else return
    req.httpBody = httpBody

    let session = URLSession.shared

    session.dataTask(with: req, completionHandler: (data, response, error) in
        if let response = response 
            // print(response)
        
        if let data = data 

            do
                let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
                print("the json for make payment \(json)")

                let loanDetails = json["loan_details"] as! [String : Any]
                let dueAmount = loanDetails["emi_amount"] as? String

                    DispatchQueue.main.async 

                        self.dueamountLabel.text = dueAmount

                    

            catch
                print("error")
            
        
    ).resume()



@IBAction func searchBtnTapped(_ sender: Any) 
    makePaymentService()



对于每个家庭 ID,我为 MakePaymentViewController 获取单独的 json。如果我们从家中选择第二张 id 图像,则需要在 MakePaymentViewController 中显示这些详细信息。如果我们选择 45 那么这些细节。

如果我选择任何主页项目,我将转到 MakePaymentViewController 并仅显示 id 2 详细信息。但我想要根据 ids 的个人详细信息。

请帮助我编写代码。

【问题讨论】:

【参考方案1】:

在你的第二个控制器上创建变量

class MakePaymentViewController: UIViewController 
    var id = ""

在推动第二个 Controller 时,根据选定的 Cell 设置 id 的值。

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 

        //let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
        let nextViewController = self.storyboard?.instantiateViewController(withIdentifier: "MakePaymentViewController") as! MakePaymentViewController

        let selectedJson =  financerArray[indexpath.row]

        let indexPathHome = indexPath.row
        print("home collectionItem indexpath \(indexPathHome)")
nextViewController.id =  selectedJson["id"]

self.navigationController?.pushViewController(nextViewController, animated: true)

    

将 Id 的值传递给 api。

func makePaymentService()

    let parameters = ["assessmentNo":  Int(serviceNumTextField.text ?? ""),
                      "id": id,
                      ] as? [String : Any]

    let url = URL(string: "https://dev.emi.com/webservice/emi/getassment_details")
    var req =  URLRequest(url: url!)
    req.httpMethod = "POST"
    req.addValue("application/json", forHTTPHeaderField: "Contet-Type")
    req.addValue("application/json", forHTTPHeaderField: "Accept")

    guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else return
    req.httpBody = httpBody

    let session = URLSession.shared

    session.dataTask(with: req, completionHandler: (data, response, error) in
        if let response = response 
            // print(response)
        
        if let data = data 

            do
                let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
                print("the json for make payment \(json)")

                let loanDetails = json["loan_details"] as! [String : Any]
                let dueAmount = loanDetails["emi_amount"] as? String

                    DispatchQueue.main.async 

                        self.dueamountLabel.text = dueAmount

                    

            catch
                print("error")
            
        
    ).resume()


【讨论】:

以上是关于如何在Swift中根据json id(意味着indexPath应该与json id匹配)从collectionView didSelectItemAt indexPath pushViewContro的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Alamofire SWIFT 在 post api 中发送 JSON

在 Swift 中,如何从 UITableView 中获取对象 id 并根据对象 id 删除对象?

如何在 Swift 4 的 NSObject 类中初始化 json 内的数组?

如何使用 Alamofire 在 Xcode 8 Swift 3.0 中获取特定的 JSON?

如何在 Swift 中访问 JSON 响应中的特定数据

根据其他ID参数过滤Fullcalendar事件