2016-04-01 7 views
0

私は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() 
}) 

私は正常にそれがself.tableView.reloadData()を実行するreloadtable()機能を呼び出すことを、確認しています。私が立ち往生している場所は、その後、tableViewは実際にリロードされません。私はif let activity = Activity(rawValue: indexPath.row) {という行にブレークポイントを設定し、reloadtable()関数が実際にトリガーされたことを確認できたとしても、ブレークポイントが2度目にトリガーされないため、わかります。私はここで間違って何をしています、なぜテーブルが再ロードされていませんか?ありがとう!ここで

EDIT

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 
    } 


} 
+0

あなたの 'self.tableView.dataSource = self'は本当ですか? – aimak

+0

テーブルに現れる行は、同じswiftファイルの 'enum'で定義されていますが、クラス定義の外にあります。あなたが何を意味するかわからない。しかし、 'cellForRowAtIndexPath'の中にフィルタがあることが分かります。 –

+0

' UITableView'' reloadData()が呼び出されると、 'UITableViewDataSource'から情報を呼び出します。あなたのコードから、 'ActivityViewController'は' self.tableView'のdataSourceでなければなりません。 – aimak

答えて

1

問題がActivityViewController().reloadtable()呼び出しです。これにより、Dataクラスがデータをダウンロードするたびに新しいActivityViewControllerが作成されます。すでに存在する(画面に表示されている)同じActivityViewControllerインスタンスでreloadtable()とだけ電話することが重要です。 (基本的な単純な)ソリューションは、以下のリファクタリングを行うことであろう

一つの良い:

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() 
    } 
    } 
} 

ここでも、これはうまくいくはずの基本的な解決策です。重要な教訓は、必要なときにクラスの新しいインスタンスを作成しないことです。

+0

神聖な*働いた。どうもありがとうございます!今、私はちょうどサーバーコールが繰り返し行われていることを知っています。私は実際にそれを一度作る必要がありますが、ここからは分かりません。本当に便利な技術を私にくれました! –

+1

リクエストは 'cellForRow'で行われます。これは、セルが表示されるたびに意味します。 – aimak

+0

うん、私はそれを気づいてから、その関数の中からデータをリロードするように呼びます... 'cellForRow'の外からテーブルをリロードするために呼び出すことは可能ですか? –