很难重新加载UITableView

时间:2016-04-01 14:06:44

标签: ios swift uitableview

我正在使用以下类成功将一行加载到UITableView。

import UIKit
import ResearchKit

enum Activity: Int {
    case Demographics

    static var allValues: [Activity] {
        var idx = 0
        return Array(anyGenerator{ return self.init(rawValue: idx++)})
    }

    var title: String {
        switch self {
        case .Demographics:
            return "Demographics"
        }
    }

    var subtitle: String {
        switch self {
            case .Demographics:
                return "Demographics Survey"
        }
    }
}

class ActivityViewController: UITableViewController {

    // MARK: UITableViewDataSource

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard section == 0 else { return 0 }

        return Activity.allValues.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("activityCell", forIndexPath: indexPath)

        if let activity = Activity(rawValue: indexPath.row) {
            cell.textLabel?.text = activity.title
            cell.detailTextLabel?.text = activity.subtitle
            if (activity.title == "Demographics"){
                if (Data().is_demo_complete()){
                    cell.textLabel?.textColor = UIColor.lightGrayColor()
                    cell.detailTextLabel?.textColor = UIColor.lightGrayColor()
                    cell.userInteractionEnabled = false
                }
            }
        }

        return cell
    }

    func reloadtable(){
        self.tableView.reloadData()
    }

    // MARK: UITableViewDelegate

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        guard let activity = Activity(rawValue: indexPath.row) else { return }

        let taskViewController: ORKTaskViewController
        switch activity {
            case .Demographics:
                taskViewController = ORKTaskViewController(task: DemoTask, taskRunUUID: NSUUID())


        }

        taskViewController.delegate = self
        navigationController?.presentViewController(taskViewController, animated: true, completion: nil)
    }
}

我有另一个名为Data的类,我将所有通信存储到我的服务器。我的想法是我必须检查服务器上的一些数据,以了解是否灰显并禁用tableView中的一行。从数据类,当服务器调用完成并成功时,我这样做:

dispatch_async(dispatch_get_main_queue(), { () -> Void in
    ActivityViewController().reloadtable()
})

我已经确认,已成功调用reloadtable()函数,该函数运行self.tableView.reloadData()。我被困的地方是,之后,tableView实际上没有重新加载。我可以说,因为我在if let activity = Activity(rawValue: indexPath.row) {的行上设置了一个断点,并且第二次断点没有被触发,即使我可以确认reloadtable()函数确实被触发了。我在这里做错了什么,为什么不重新加载表?谢谢!

修改

以下是Data类:

class Data: NSObject, NSURLSessionDelegate {

    var unique_id = UIDevice.currentDevice().identifierForVendor!.UUIDString;

    var demo_complete = false

    func check_demo_complete(){

        let request = NSMutableURLRequest(URL: NSURL(string: "https://www.myurl.com/is_demo_complete.php")!)
        request.HTTPMethod = "POST"
        let postString = "unique_id=\(unique_id)&pass=somepass"
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

        let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)

        let task = session.dataTaskWithRequest(request) {
            data, response, error in

            if error != nil {
                print("error=\(error)")
                return
            }

            let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)

            if ( responseString == "true" ) {
                self.demo_complete = true
                print ("Demo has been completed")
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    ActivityViewController().reloadtable()
                })
            }
        }
        task.resume()
    }

    func is_demo_complete() -> Bool{
        return self.demo_complete
    }


}

1 个答案:

答案 0 :(得分:1)

问题是ActivityViewController().reloadtable()电话。每次ActivityViewController类下载数据时,都会创建一个新的Data。请务必仅在已存在的同一reloadtable()实例上调用ActivityViewController(并在屏幕上显示)。

一个好的(基本但简单的)解决方案是进行以下重构:

func check_demo_complete(completion:(Bool -> ()){
  // your network call
  dispatch_async(dispatch_get_main_queue()) {
    if ( responseString == "true" ) {
      completion(true)
    }
    else {
      completion(false)
    }
    // or, simpler : completion(responseString == "true")
  }
}

这样,通过致电check_demo_complete(),您就有义务通过关闭:

if (activity.title == "Demographics"){
  Data().check_demo_complete() { [weak self] success in
     if success {
       // change your textColors etc
       self?.tableView.reloadData()
     }
  }
}

同样,这是一个应该有效的基本解决方案。要学习的重要一课是:每次需要时都不要创建新的类实例。