2016-12-20 2 views
0

Я строю свое приложение в Swift 3 с Alamofire. У меня есть данные JSON, входящие в список. Каждый раз, когда я пытаюсь обновить контент, вместо обновления содержимого он просто добавляет больше элементов в нижнюю часть списка в виде списка, а не обновляет видимый список. Я не знаю, что я могу делать неправильно, мой код до сих пор:Pull to refresh not working

import UIKit 
import Alamofire 
import SVProgressHUD 

struct postinput { 
    let mainImage : UIImage! 
    let name : String! 
    let author : String! 
    let summary : String! 
    let content : String! 


} 


class TableViewController: UITableViewController { 

    //var activityIndicatorView: UIActivityIndicatorView! 

    var postsinput = [postinput]() 

    var refresh = UIRefreshControl() 

    var mainURL = "https://www.example.com/api" 

    typealias JSONstandard = [String : AnyObject] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     tableView.separatorStyle = UITableViewCellSeparatorStyle.none 


     self.tableView.addSubview(refresh) 

     //;refresh.attributedTitle = NSAttributedString(string: "Refreshing...", attributes:[NSForegroundColorAttributeName : UIColor.black]) 
     refresh.backgroundColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.0) 
     //refresh.tintColor = UIColor.white 

     refresh.addTarget(self, action: #selector(self.refreshData), for: UIControlEvents.valueChanged) 
     //refresh.addTarget(self, action: #selector(getter: TableViewController.refresh), for: UIControlEvents.valueChanged) 
     refresh.attributedTitle = NSAttributedString(string: "Updated: \(NSDate())") 


     //activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray) 
     //tableView.backgroundView = activityIndicatorView 

     callAlamo(url: mainURL) 


    } 

    func refreshData() { 

     Alamofire.request("https://www.example.com/api").responseJSON(completionHandler: { 
      response in 
      self.parseData(JSONData: response.data!) 
      self.tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine 

      DispatchQueue.main.async { 
       self.tableView.reloadData() 
       self.refresh.endRefreshing() 
      } 


     }) 



    } 



    func callAlamo(url : String){ 
     //activityIndicatorView.startAnimating() 
     SVProgressHUD.show(withStatus: "Loading...") 
     SVProgressHUD.setDefaultStyle(SVProgressHUDStyle.dark) 
     SVProgressHUD.setDefaultAnimationType(SVProgressHUDAnimationType.native) 
     SVProgressHUD.setDefaultMaskType(SVProgressHUDMaskType.black) 
     Alamofire.request(url).responseJSON(completionHandler: { 
      response in 
      self.parseData(JSONData: response.data!) 
      self.tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine 
      //self.activityIndicatorView.stopAnimating() 
      SVProgressHUD.dismiss() 


     }) 


    } 


    func parseData(JSONData : Data) { 
     do { 
      var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONstandard 
      // print(readableJSON) 

      if let posts = readableJSON["posts"] as? [JSONstandard] { 
       for post in posts { 
        let title = post["title"] as! String 

        let author = post["author"] as! String 

        guard let dic = post["summary"] as? [String: Any], let summary = dic["value"] as? String else { 
         return 
        } 
        let str = summary.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil) 
        print(str) 

        guard let dic1 = post["content"] as? [String: Any], let content = dic1["value"] as? String else { 
         return 
        } 
        let str1 = content.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil) 
        print(str1) 





        //print(author) 

        if let imageUrl = post["image"] as? String { 
         let mainImageURL = URL(string: imageUrl) 
         let mainImageData = NSData(contentsOf: mainImageURL!) 
         let mainImage = UIImage(data: mainImageData as! Data) 

         postsinput.append(postinput.init(mainImage: mainImage, name: title, author: author, summary: summary, content: content)) 
        } 
       } 
       DispatchQueue.main.async { 
        self.tableView.reloadData() 
       } 
      } 


     } 


     catch { 
      print(error) 
     } 


    } 


    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return postsinput.count 
    } 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "cell") 

     // cell?.textLabel?.text = titles[indexPath.row] 

     let mainImageView = cell?.viewWithTag(2) as! UIImageView 

     mainImageView.image = postsinput[indexPath.row].mainImage 

     mainImageView.layer.cornerRadius = 5.0 
     mainImageView.clipsToBounds = true 

     //(cell?.viewWithTag(2) as! UIImageView).image = postsinput[indexPath.row].mainImage 

     let mainLabel = cell?.viewWithTag(1) as! UILabel 

     mainLabel.text = postsinput[indexPath.row].name 

     mainLabel.font = UIFont.boldSystemFont(ofSize: 18) 

     mainLabel.sizeToFit() 

     mainLabel.numberOfLines = 0; 

     let autLabel = cell?.viewWithTag(3) as! UILabel 

     autLabel.text = postsinput[indexPath.row].author 

     autLabel.font = UIFont(name: "Helvetica", size:16) 

     autLabel.textColor = UIColor(red: 0.8784, green: 0, blue: 0.1373, alpha: 1.0) /* #e00023 */ 

     let sumLabel = cell?.viewWithTag(4) as! UILabel 

     sumLabel.text = (postsinput[indexPath.row].summary).replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil) 

     sumLabel.font = UIFont(name: "Helvetica", size:16) 

     sumLabel.textColor = UIColor(red:0.27, green:0.27, blue:0.27, alpha:1.0) 

     //let contentLabel = cell?.viewWithTag(0) as! UILabel 

     //contentLabel.text = (postsinput[indexPath.row].content).replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil) 



     //(cell?.viewWithTag(3) as! UILabel).text = postsinput[indexPath.row].author 

     return cell! 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     SVProgressHUD.show() 
     let indexPath = self.tableView.indexPathForSelectedRow?.row 

     let vc = segue.destination as! nextVC 


     vc.articleImage = postsinput[indexPath!].mainImage 
     vc.articleMainTitle = postsinput[indexPath!].name 
     vc.articleContent = postsinput[indexPath!].content 
     SVProgressHUD.dismiss() 

     let backItem = UIBarButtonItem() 
     backItem.title = "Back" 
     navigationItem.backBarButtonItem = backItem // This will show in the next view controller being pushed 



    } 


    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
     if editingStyle == .delete { 
      postsinput.remove(at: indexPath.row) 
      tableView.deleteRows(at: [indexPath], with: .fade) 
     } else if editingStyle == .insert { 
      // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view. 
     } 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 

ответ

1

Ваша задача здесь, чтобы обновить, - это просто обновить данные, существующие в вашем списке, а также добавить новые элементы, если они есть. Итак, что вам нужно сделать, вместо того, чтобы добавлять элементы в свой список каждый раз, когда вы извлекаете обновления, вы просто предоставляете новый список, исходящий с сервера, на ваш tableView. У вас есть массив aleready postsinput, поэтому не забудьте удалить все элементы перед их добавлением. Ниже приведен код, в котором вы можете внести изменения.

func parseData(JSONData : Data) { 

    postsinput.removeAll() 

    do { 

     ... 
     ... 
       if let imageUrl = post["image"] as? String { 
        let mainImageURL = URL(string: imageUrl) 
        let mainImageData = NSData(contentsOf: mainImageURL!) 
        let mainImage = UIImage(data: mainImageData as! Data) 

        postsinput.append(postinput.init(mainImage: mainImage, name: title, author: author, summary: summary, content: content)) 
       } 
      } 
      DispatchQueue.main.async { 
       self.tableView.reloadData() 
      } 
     ... 
     ... 
} 
+0

Это буквально дубликат моего ответа. Я понятия не имею, почему это принято ... – JAL

5

Ваш вопрос здесь:

postsinput.append(postinput.init(mainImage: mainImage, name: title, author: author, summary: summary, content: content)) 

Вы сохраняете добавление новых данных в старых данных. Если вы хотите полностью очистить старые данные перед добавлением новых данных, просто удалите все элементы из массива postsinput.

+0

Но эта строка, насколько я понимаю, добавляет все элементы в список, если я удалю это, как данные попадут в список? – Sole

+0

@Sole Вы удаляете все элементы, которые в настоящее время находятся в массиве, перед добавлением новых данных, поступающих с вашего веб-запроса. – JAL

+0

У вас есть пример кода? – Sole