【问题标题】:Pull to Refresh in Swift not Reloading UITableView在 Swift 中拉动刷新而不重新加载 UITableView
【发布时间】:2014-10-23 16:57:29
【问题描述】:

我的JSON 已成功填充我的UITableView,但JSON 经常更新,因此我需要能够刷新。我跟着THIS TUTORIAL 实现了拉动刷新控制。从视觉上看,它似乎一切正常,但是当我调用tableView.reloadData() 时,表不会重新加载。但是,如果我离开 ViewController 并返回,表格就会更新。为什么tableView.reloadData() 可以在viewDidAppearviewWillAppear 中工作,但不能在我的自定义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()

    }

}

【问题讨论】:

  • 嘿大卫 - 我只是尝试复制一个没有 Web 服务调用的简单示例,我的工作正常。您在哪里将 dataArray 设置为新的 NSArray?
  • 我将添加我的 MainVC 文件的其余部分
  • 回答你的问题 Andrew,dataArray 在 connectionDidFinishLoading 函数中被推入一个新的 NSArray“结果”
  • 我在您的 connectionDidFinishLoading 方法中看到了 self.dataArray = resultstableView.reloadData()。但是,我看不到您实际上在哪里再次调用您的服务以让此回调方法在您手动拉动刷新过程中再次实际执行。 refresh 函数只是调用 tableView.reloadData(),但由于数组中没有新内容(因为没有调用 Web 服务),所以没有任何内容被重新加载...除非我在您的方法中遗漏了其他内容...跨度>
  • 我的意思是我需要再次将结果推送到刷新函数内部的新 NSArray 中吗?

标签: ios json uitableview swift pull-to-refresh


【解决方案1】:

在我看来,您的最后一条评论是正确的。

在拉取refresh 函数期间,您调用tableView.reloadData(),但是,reloadData() 本质上不会重新填充数据源中的元素(在您的情况下为dataArray)。它只是在调用它时重新加载当前表视图的数据源中的所有数据。

所以我的建议是构建您的 refresh 函数,以便发生以下情况:

  1. 向您的网络服务发起请求。
  2. 当响应返回时(即connectionDidFinishLoading 被执行),解析JSON 结果并将该结果分配给dataArray 实例。您似乎已经在 connectionDidFinishLoading 中执行此操作,所以我认为只需将请求发送到您的网络服务即可。
  3. 调用tableView.reloadData() 以显示自上次显示tableView 的数据以来添加的任何新元素。同样,您已经在 connectionDidFinishLoading 中执行此操作,因此我认为第一件事是需要发生的主要事情。

【讨论】:

    【解决方案2】:

    参考https://stackoverflow.com/a/25957339

    不确定,但可能连接在不同的线程上运行,如果是这样,您需要在主 UI 线程上运行表更新

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多