Потяните, чтобы обновить в Swift, не перезагружая UITableView

У меня есть JSON наполняя мой UITableView успешно, но JSON часто обновляется, поэтому мне нужна возможность обновить. Я следовал ЭТОМУ ОБУЧЕНИЮ, чтобы реализовать управление обновлением. Визуально вроде все работает правильно, но когда я звоню tableView.reloadData() таблица не перезагружается. Однако, если я оставлю ViewController и возвращаем, таблица обновляется. Почему бы tableView.reloadData() работать в viewDidAppear а также viewWillAppear но не в моем обычае refresh() функционировать?

Файл 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()

    }

}

2 ответа

Решение

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

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

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

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

Ссылаясь на /questions/5618986/selftableviewreloaddata-ne-rabotaet-v-swift/5618999#5618999

Не уверен, но, возможно, соединение запущено в другом потоке, если вам нужно запустить обновление таблицы в основном потоке пользовательского интерфейса

// using Swift's trailing closure syntax:
dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadData()
}
Другие вопросы по тегам