2014-08-29 2 views
3

У меня есть JSON, успешно заполняя мой UITableView, но часто обновляется JSON, поэтому мне нужна возможность обновления. Я выполнил команду THIS TUTORIAL, чтобы реализовать контроль за обновлением. Визуально кажется, что все работает правильно, но когда я звоню tableView.reloadData(), таблица не перезагружается. Однако, если я оставлю ViewController и вернусь, таблица будет обновлена. Почему бы tableView.reloadData() работать в viewDidAppear и viewWillAppear, но не в моем обычном refresh() функция?Pull to Refresh in Swift не перезагружается UITableView

MainVC.swift файл

class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource { 

     @IBOutlet var tableView: UITableView! 
     var dataArray: NSArray = NSArray() 

     @IBOutlet var Controller: UISegmentedControl! 

     var refreshControl:UIRefreshControl! 

     func refresh(sender:AnyObject) 
     { 
      refreshBegin("Refresh", 
       refreshEnd: {(x:Int) ->() in 
        self.tableView .reloadData() 
        println("Table Reloaded") 
        self.refreshControl.endRefreshing() 
      }) 
     } 

     func refreshBegin(newtext:String, refreshEnd:(Int) ->()) { 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
       println("refreshing") 
       sleep(2) 

       dispatch_async(dispatch_get_main_queue()) { 
        refreshEnd(0) 
       } 
      } 
     } 

     override func viewWillAppear(animated: Bool) { 
      self.tableView .reloadData() 
     } 

     override func viewDidLoad() { 
      super.viewDidLoad() 
      navigationItem.titleView = UIImageView(image: UIImage(named: "logojpg.jpg")) 
      startConnectionAt("http://www.domain.com/json.php") 


      refreshControl = UIRefreshControl() 
      refreshControl.backgroundColor = UIColor.orangeColor() 
      refreshControl.tintColor = UIColor.whiteColor() 
      refreshControl.attributedTitle = NSAttributedString(string: "Pull to Refresh") 
      refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged) 
      tableView.addSubview(refreshControl) 

      } 

//MARK: JSON Loading 

    var data: NSMutableData = NSMutableData() 
    func startConnectionAt(urlPath: String){ 
     var url: NSURL = NSURL(string: urlPath) 
     var request: NSURLRequest = NSURLRequest(URL: url) 
     var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false) 
     connection.start() 
    } 

    func connection(connection: NSURLConnection!, didFailWithError error: NSError!) { 
     println("Connection failed.\(error.localizedDescription)") 
    } 

    func connection(connection: NSURLConnection, didRecieveResponse response: NSURLResponse) { 
     println("Recieved response") 
    } 

    func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) { 
     self.data = NSMutableData() 
    } 

    func connection(connection: NSURLConnection!, didReceiveData data: NSData!) { 
     self.data.appendData(data) 
    } 

    func connectionDidFinishLoading(connection: NSURLConnection!) { 
     var dataAsString: NSString = NSString(data: self.data, encoding: NSUTF8StringEncoding) 
     var err: NSError 
     var json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary 
     var results: NSArray = json["needs"] as NSArray 
     self.dataArray = results 

     tableView.reloadData() 
     println("success") 
    } 

//End loading of JSON 

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

    func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { 
     return self.dataArray.count; 
    } 

    func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! { 
     var cell:CustomCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as CustomCell 

     var rowData: NSDictionary = dataArray[indexPath.row] as NSDictionary 
     var firstName=rowData["needFirstname"] as String 
     var descrip=rowData["needDescription"] as String 
     var poster=rowData["needPoster"] as String 
     var city=rowData["needCity"] as String 
     var state=rowData["needState"] as String 
     var country=rowData["needCountry"] as String 

     cell.needFirstName.text = firstName 
     cell.needDescription.text = descrip 
     cell.needDescription.numberOfLines = 0 
     cell.needPoster.text = poster 
     cell.needCity.text = city 
     cell.needState.text = state 
     cell.needCountry.text = country 

     return cell 
    } 


    @IBAction func Change(sender: AnyObject) { 

     if Controller.selectedSegmentIndex == 0 { 
      startConnectionAt("http://www.domain.com/localJSON.php") 
     } 
     else if Controller.selectedSegmentIndex == 1 { 
      startConnectionAt("http://www.domain.com/intlJSON.php") 
     } 

     self.tableView .reloadData() 

    } 

} 
+1

Эй Дэвид - Я просто попытался воспроизвести простой пример без вызовов веб-сервисов и моей работы. Где вы устанавливаете dataArray для нового NSArray? – andrewcbancroft

+0

Я добавлю остальную часть моего файла MainVC – davidrayowens

+0

Чтобы ответить на вопрос Andrew, dataArray вводится в новый результат NSArray в функции connectionDidFinishLoading – davidrayowens

ответ

5

Ваш последний комментарий отменный, на мой взгляд.

Во время тянуть к refresh функции, вы звоните tableView.reloadData(), однако, reloadData() по своей природе не делать какие-либо заселив элементов в источнике данных (в вашем случае, dataArray). Он просто перезагружает все данные, которые в настоящее время находятся в , в источнике данных представления таблицы в момент его вызова.

Так что моя рекомендация будет построить свой refresh функцию таким образом, что происходит следующее:

  1. инициируют запрос веб-службы.
  2. Когда возвращается ответ (т. Е. Выполняется connectionDidFinishLoading), проанализируйте результаты JSON и присвойте этот результат экземпляру dataArray. Вы, кажется, делаете это уже в connectionDidFinishLoading, так что я просто думаю, что это просто вопрос отправки запроса на ваш веб-сервис.
  3. Вызвать tableView.reloadData() для отображения любых новых элементов, которые были добавлены с момента последнего отображения данных таблицыView. Опять же, вы делаете это уже в connectionDidFinishLoading, поэтому # 1 - это основная вещь, которая, как мне кажется, должна произойти.
4

Ссылаясь на https://stackoverflow.com/a/25957339

Не уверен, но, возможно, подключение выполняется в другом потоке, если так что вам нужно, чтобы запустить обновление таблицы на главном UI потоке

// using Swift's trailing closure syntax: 
dispatch_async(dispatch_get_main_queue()) { 
    self.tableView.reloadData() 
} 
+0

Обновить таблицу в mainThread в быстром http: // stackoverflow.ком/вопросы/24126261/быстроногих альтернатива к performselectoronmainthread/31853168 # 31853168 –

+0

Это нуждается в parentesis :) dispatch_async (dispatch_get_main_queue()) { self.tableView.reloadData()} –