Tableview 行没有在 swift 中显示带有附加值的顺序

Posted

技术标签:

【中文标题】Tableview 行没有在 swift 中显示带有附加值的顺序【英文标题】:Tableview rows are not showing inorder with added values in swift 【发布时间】:2020-06-25 06:59:37 【问题描述】:

我在配置文件视图控制器中收到 JSON 响应。最初 JSON 包含一个我需要在 tableview 中显示的地址,然后我将新地址从 thirdviewcontroller 添加到第一个 viewcontroller JSON...

现在我需要在配置文件视图控制器 INORDER 中更新初始地址和所有添加的新地址.. 怎么样?

如果我在 profileviewcontroller 中添加如下内容,则 tableview 未按地址顺序显示:这里初始地址下降,添加的新地址也分散......我需要初始地址索引 0 和新地址位于索引 1...

class ProfileViewController: UIViewController, MyCellDelegate 

@IBOutlet var addressTableview: UITableView!
var userModel : ProfileModel?

override func viewWillAppear(_ animated: Bool) 
    self.navigationController?.navigationBar.isHidden=true
    DispatchQueue.main.async 
        self.getUserProfile()
    


func getUserProfile() 

    let urlStr = urlComponents?.url
    
    let request = NSMutableURLRequest(url: urlStr!, cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
    request.httpMethod = "POST"
    let session = URLSession.shared
    let dataTask = session.dataTask(with: request as URLRequest, completionHandler:  (data, response, error) -> Void in
        if error == nil 
            let httpResponse = response as? HTTPURLResponse
            if httpResponse!.statusCode == 200 
                do 
                    let jsonObject  = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String :AnyObject]
                    self.userModel = ProfileModel.init(fromDictionary: jsonObject)
                    if (self.userModel?.userId) != nil 
                      
                        DispatchQueue.main.async 
                            self.addressTableview.reloadData()
                        
                    
                 catch  print(error.localizedDescription) 
            
    )
    dataTask.resume()



extension ProfileViewController : UITableViewDelegate,UITableViewDataSource, CLLocationManagerDelegate 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    
    return userModel?.userAddresses.count ?? 0

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        
    let cell: AddresCell = tableView.dequeueReusableCell(withIdentifier: "AddresCell", for: indexPath) as! AddresCell
    
    let addr = userModel?.userAddresses![indexPath.row]
    
        cell.name.text    = addr?.type
        cell.typeAddLabel.text = addr?.addressName
                  let street = addr?.streetName
                  let colony = addr?.colony
                  let city   = addr?.city
                   let pincode = addr?.pincode
        let locality: String = addr?.buildingName ?? ""
        let dorNum: String = addr?.houseNo ?? ""
        cell.address.text = street! + "," + colony! + "," + city! + "," + pincode! + "," + locality + "," + dorNum
        return cell
    
    

我错在哪里,如何按顺序排列表格视图,请不要介意我卡在这里很久了

这是 ProfileModel 代码:

 class ProfileModel  : NSObject, NSCoding

var userId : String!

var userAddresses : [ProfileModelUserAddress]!

init(fromDictionary dictionary: [String:Any])
    userId = dictionary["userId"] as? String
    userAddresses = [ProfileModelUserAddress]()
    if let userAddressesArray = dictionary["userAddresses"] as? [[String:Any]]
        for dic in userAddressesArray
            let value = ProfileModelUserAddress(fromDictionary: dic)
            userAddresses.append(value)
        
    

func toDictionary() -> [String:Any]

    var dictionary = [String:Any]()
    if userId != nil
        dictionary["userId"] = userId
    
    if userAddresses != nil
        var dictionaryElements = [[String:Any]]()
        for userAddressesElement in userAddresses 
            dictionaryElements.append(userAddressesElement.toDictionary())
        
        dictionary["userAddresses"] = dictionaryElements
    
    return dictionary

@objc required init(coder aDecoder: NSCoder)

    userId = aDecoder.decodeObject(forKey: "userId") as? String
    userAddresses = aDecoder.decodeObject(forKey: "userAddresses") as? [ProfileModelUserAddress]

@objc func encode(with aCoder: NSCoder)

    if userId != nil
        aCoder.encode(userId, forKey: "userId")
    
    if userAddresses != nil
        aCoder.encode(userAddresses, forKey: "userAddresses")
    


ProfileModel 的var userAddresses : [ProfileModelUserAddress] 的代码:

class ProfileModelUserAddress : NSObject, NSCoding

var addressId : String!
var addressName : String!
var userId : String!
var pincode : String!
var city : String!
var streetName : String!

init(fromDictionary dictionary: [String:Any])
    addressId = dictionary["addressId"] as? String
    addressName = dictionary["addressName"] as? String
    userId = dictionary["userId"] as? String
    pincode = dictionary["pincode"] as? String
    city = dictionary["city"] as? String
    streetName = dictionary["streetName"] as? String
    

func toDictionary() -> [String:Any]

    var dictionary = [String:Any]()
    if addressId != nil
        dictionary["addressId"] = addressId
    
    if addressName != nil
        dictionary["addressName"] = addressName
    
    if userId != nil
        dictionary["userId"] = userId
    
    if pincode != nil
        dictionary["pincode"] = pincode
    
    if city != nil
        dictionary["city"] = city
    
    if streetName != nil
        dictionary["streetName"] = streetName
    
    
    return dictionary

@objc required init(coder aDecoder: NSCoder)

    addressId = aDecoder.decodeObject(forKey: "addressId") as? String
    addressName = aDecoder.decodeObject(forKey: "addressName") as? String
    userId = aDecoder.decodeObject(forKey: "userId") as? String
    pincode = aDecoder.decodeObject(forKey: "pincode") as? String
    city = aDecoder.decodeObject(forKey: "city") as? String
    streetName = aDecoder.decodeObject(forKey: "streetName") as? String
  

@objc func encode(with aCoder: NSCoder)

    if addressId != nil
        aCoder.encode(addressId, forKey: "addressId")
    
    if addressName != nil
        aCoder.encode(addressName, forKey: "addressName")
    
    if userId != nil
        aCoder.encode(userId, forKey: "userId")
    
    if pincode != nil
        aCoder.encode(pincode, forKey: "pincode")
    
    if city != nil
        aCoder.encode(city, forKey: "city")
    
    if streetName != nil
        aCoder.encode(streetName, forKey: "streetName")
    


我正在从这个 viewcontroller 向 profileviewcontroller tableview 添加新地址:

 class NewZoomAddressViewController: UIViewController 

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) 
let center = getCenterLocation(for: mapView)
let geoCoder = CLGeocoder()

guard let previousLocation = self.latestLocation else  return 

guard center.distance(from: previousLocation) > 50 else  return 
self.previousLocation = center

let userLocation :CLLocation = center as CLLocation
latitudeZoom = userLocation.coordinate.latitude
logitudeZoom = userLocation.coordinate.longitude

geoCoder.reverseGeocodeLocation(center)  [weak self] (placemarks, error) in
    guard let self = self else  return 
    self.streetNumber = placemark.subThoroughfare ?? ""
    self.streetName = placemark.thoroughfare ?? ""
    self.localityName = placemark.locality ?? ""//locality
    self.sublocalityName = placemark.subLocality ?? ""//locality
    self.zipName = placemark.postalCode ?? ""//locality
    





@IBAction func popupSubmitBtn(_ sender: Any) 

if addressTextfield != nil
    self.saveaddAddressService()



func saveaddAddressService()

let parameters: [String: Any] = [
                 "pincode": zipName,
                 "city": localityName,
                 "streetName": sublocalityName,
                 "colony": "",
                 "location" : locations,
                 "addressName" : addressTextfield.text
             ]

         do 
              let jsonObject  = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String: Any]
              print("saved address json \(jsonObject)")

              self.addAddrsID = jsonObject["addressId"] as! String
                        
              UserDefaults.standard.set(self.addAddrsID, forKey: "addAddress")
             DispatchQueue.main.async 
                            let viewController = self.storyboard?.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
                            self.navigationController?.pushViewController(viewController, animated: true)
                
              
                 catch  print(error.localizedDescription) 
                 else 

                
            
        )
        dataTask.resume()
    
 

profileviewcontroller json 响应:所有地址的用户 ID 相同。但每个新地址都会有新地址 ID

    
    addressId = 5ef48787f546e73ee823f032;
    addressName = ban;
    
    city = Bengaluru;
    dateCreated = "25-06-2020 16:46:23";
    dateModified = "25-06-2020 16:46:23";
    pincode = 560001;
   
    userId = 85dc157688d84aab9bbbab150cbc13da;
    ,
   
    addressId = 5ef48828f546e73ee823f033;
    addressName = chen;
    dateCreated = "25-06-2020 16:49:04";
    landMark = "";
   
    pincode = 600095;
    streetName = Maduravoyal;
    userId = 85dc157688d84aab9bbbab150cbc13da;
   ,
   
    addressId = 5ef46670f546e73ee823f020;
    addressName = vizag;
    
    city = Visakhapatnam;
    colony = "";
    dateCreated = "25-06-2020 14:25:12";
    
    pincode = 530045;
   
    userId = 85dc157688d84aab9bbbab150cbc13da;
     ,
     
    addressId = 5ef4664af546e73ee823f01c;
   

【问题讨论】:

你能显示userModel。也许您可以在模型中添加另一个变量addedAt,并根据该变量对数组进行排序 这是您的第三个几乎相同的问题。如果没有更多信息,即使是这个问题也无法回答。 updateUserDetails() 是什么?型号是什么?您如何将新地址从 thirdviewcontroller 添加到第一个 ViewController @vadian.. 我已经用所有相关代码编辑了我的帖子.. updateUserDetails() 与 tableview 无关.. 请看一下 @Mat..我已经用所有 userModel 编辑了我的帖子。请看看并提供帮助 @vadian 任何建议.. 我错了 【参考方案1】:

在您的模型中为ProfileModelUserAddress 添加一个新变量来保存dateCreated

class ProfileModelUserAddress : NSObject, NSCoding

    // add this variable
    var dateCreated : Date!
    //.... your other variables 

    init(fromDictionary dictionary: [String:Any])
       let formatter = DateFormatter()

       formatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
       //convert your string to date
       dateCreated = formatter.date(from: dictionary["dateCreated"] as! String)
       //....the rest of your code
    

然后在你的ProfileViewController

class ProfileViewController: UIViewController, MyCellDelegate 

   var userModel : ProfileModel?
   // added this array which will hold all your addresses 
   var addressModel =  [ProfileModelUserAddress]()

   func getUserProfile() 
      // if you call this fucntion again everytime you add 
      // a new address, call removeAll() in order to have an 
      //empty array, otherwise you will end up with double values.
      self.addressModel.removeAll()
      //.... rest of your code

      let jsonObject  = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String :AnyObject]
      self.userModel = ProfileModel.init(fromDictionary: jsonObject)
         for address in userModel!.userAddresses! 
            addressModel.append(address)
         
     self.addressModel.sort(by:  $0.dateCreated!.compare($1.dateCreated!) == .orderedDescending)
      //.....
      //.... rest of your code
   

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
     // rest of your code ....
     // You can use your addresses array
     let addr = self.addressModel[indexPath.row]
     // rest of your code ....
  


我测试了它并且它有效:

func getUserProfile() 
   // All dictionaries have the same values except for the date
   let address1 = ["addressId" : "5ef48828f546e73ee823f033", "addressName": "chen","dateCreated": "25-06-2020 16:49:04", "landMark": "", "pincode": "879327" ,"streetName": "Maduravoyal", "userId": "947384783749" ]
   let address2 = ["addressId" : "5ef48828f546e73ee823f033", "addressName": "chen","dateCreated": "27-06-2020 16:49:04", "landMark": "", "pincode": "879327" ,"streetName": "Maduravoyal", "userId": "947384783749" ]
   let address3 = ["addressId" : "5ef48828f546e73ee823f033", "addressName": "chen","dateCreated": "25-06-2020 19:49:04", "landMark": "", "pincode": "879327" ,"streetName": "Maduravoyal", "userId": "947384783749" ]
   let address4 = ["addressId" : "5ef48828f546e73ee823f033", "addressName": "chen","dateCreated": "29-06-2020 19:49:04", "landMark": "", "pincode": "879327" ,"streetName": "Maduravoyal", "userId": "947384783749" ]

   let addressObj = ProfileModelUserAddress.init(fromDictionary: address1)
   let addressObj1 = ProfileModelUserAddress.init(fromDictionary: address2)
   let addressObj2 = ProfileModelUserAddress.init(fromDictionary: address3)
   let addressObj3 = ProfileModelUserAddress.init(fromDictionary: address4)

   var addresseTry = [ProfileModelUserAddress]()
   addresseTry.append(addressObj)
   addresseTry.append(addressObj1)
   addresseTry.append(addressObj2)
   addresseTry.append(addressObj3)
      for address in addresseTry 
         addressModel.append(address)
      

   self.addressModel.sort(by:  $0.dateCreated!.compare($1.dateCreated!) == .orderedDescending)
   
      for addressForDate in self.addressModel 
         print(addressForDate.dateCreated)
      

哪个打印:

Optional(2020-06-29 16:49:04 +0000)
Optional(2020-06-27 13:49:04 +0000)
Optional(2020-06-25 16:49:04 +0000)
Optional(2020-06-25 13:49:04 +0000)

【讨论】:

谢谢,地址是按顺序添加的,但是如果我去 otherviewcontroller 并返回,那么相同的地址数组会在 tableview 中添加两次 添加新地址后是否再次调用getUserProfile? @swiftios 检查更新的答案。如果在用户添加新地址后再次从服务器中提取数据,请使用 self.addressModel.removeAll() 是的,现在它可以工作了.. 除了 datesort 之外还有其他方法吗.. 我们可以对 addressId 进行排序吗?

以上是关于Tableview 行没有在 swift 中显示带有附加值的顺序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 中的 tableview 中的 numberOfRowsInSection 中比较和显示不同的数组计数

表单内的 TableView 没有正确显示 Swift

Swift:如何在 TableView 内的 CollectionView 中显示解析的 JSON 数据?

在tableView swift的单元格页脚视图中复制行

如何在 Swift 中的 tableview 之间显示单独的 View(box)

NSIndexPath?在 Swift 中没有成员名称“行”错误