2014-10-17 71 views
0

我有這個代碼從加載數據在Swift的TableView中解析。 的問題,我有:TableViewController在objectAtIndex之前等待加載數據

  • 當我觸摸一個細胞,這是開放與小區的相關信息 詳細視圖但是,當我返回列表視圖,並觸及另一個細胞快速,數據不加載和我有一個錯誤:

NSRangeException」,原因: '*** - [__ NSArrayM objectAtIndex:]:索引2 超出界限爲空數組'

我可以強制等待視圖來加載所有的單元格數據,然後我可以觸摸一些東西? 我可以把loadData()調用在viewDidLoad方法,但這種方式,我會力給每個我添加了一個新的細胞時手動刷新數據,刪除單元格...等

class MasterTableViewController: UITableViewController { 

    var alertsListData:NSMutableArray = NSMutableArray() 

    func loadData(){ 
     alertsListData.removeAllObjects() 
     var currentUser = PFUser.currentUser() 
     if (currentUser != nil){ 
      var findAlertsData = PFQuery(className: "Alert") 
      findAlertsData.whereKey("user_id", equalTo:PFUser.currentUser()) 
      findAlertsData.findObjectsInBackgroundWithBlock{ 
       (objects:[AnyObject]!, error:NSError!)-> Void in 
       if (error == nil){ 
        for object in objects { 
         self.alertsListData.addObject(object) 
        } 
        self.tableView.reloadData() 
        self.refreshControl?.endRefreshing() 
       } 
      } 
     } 
    } 

    @IBAction func logoutAction(sender: AnyObject) { 
     PFUser.logOut() 
     var currentUser = PFUser.currentUser() 
    } 

    override func viewDidAppear(animated: Bool) {   
     self.loadData() 
     ... 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     var refresh = UIRefreshControl() 
     refresh.attributedTitle = NSAttributedString(string: "Tirer pour rafraîchir") 
     refresh.addTarget(self, action: "loadData", forControlEvents:.ValueChanged) 
     self.refreshControl = refresh 

     // Uncomment the following line to preserve selection between presentations 
     //self.clearsSelectionOnViewWillAppear = false 

     // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 
     // self.navigationItem.rightBarButtonItem = self.editButtonItem() 
    } 

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

    // MARK: - Table view data source 

    override func numberOfSectionsInTableView(tableView: UITableView?) -> Int { 
     // #warning Potentially incomplete method implementation. 
     // Return the number of sections. 
      return 1 
    } 

    override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int { 
     // #warning Incomplete method implementation. 
     // Return the number of rows in the section. 
     return alertsListData.count 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell:AlertTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as AlertTableViewCell 
     let alert:PFObject = self.alertsListData.objectAtIndex(indexPath.row) as PFObject 
     cell.alertTitleLabel.text = alert.objectForKey("title") as? String 
     var dateUpdated = alert.updatedAt as NSDate 
     var dateFormat = NSDateFormatter() 
     dateFormat.locale = NSLocale(localeIdentifier: "fr_FR") 
     dateFormat.dateFormat = "EEEE d, à hh:mm" 
     cell.alertDateLabel.text = NSString(format: "%@", dateFormat.stringFromDate(dateUpdated).capitalizedString) 
     var status:Bool = alert.objectForKey("status") as Bool 
     if (status == true){ 
      cell.alertStatus.text = "Terminée" 
     }else{ 
      cell.alertStatus.text = "En cours" 
     } 

     return cell 
    } 

    /* 
    // Override to support conditional editing of the table view. 
    override func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool { 
     // Return NO if you do not want the specified item to be editable. 
     return true 
    } 
    */ 

    /* 
    // Override to support editing the table view. 
    override func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) { 
     if editingStyle == .Delete { 
      // Delete the row from the data source 
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } else if editingStyle == .Insert { 
      // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 
     }  
    } 
    */ 

    /* 
    // Override to support rearranging the table view. 
    override func tableView(tableView: UITableView!, moveRowAtIndexPath fromIndexPath: NSIndexPath!, toIndexPath: NSIndexPath!) { 

    } 
    */ 

    /* 
    // Override to support conditional rearranging of the table view. 
    override func tableView(tableView: UITableView!, canMoveRowAtIndexPath indexPath: NSIndexPath!) -> Bool { 
     // Return NO if you do not want the item to be re-orderable. 
     return true 
    } 
    */ 


    // MARK: - Navigation 

    // In a storyboard-based application, you will often want to do a little preparation before navigation 
    override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject!) { 
     // Get the new view controller using [segue destinationViewController]. 
     // Pass the selected object to the new view controller. 
     if (segue!.identifier == "showDetails"){ 
      var selectedIndexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()! 
      var detailViewController:DetailViewController = segue!.destinationViewController as DetailViewController 
      detailViewController.alertData = alertsListData.objectAtIndex(selectedIndexPath.row) as PFObject 
     } 
    } 

    } 

的添加控制器是:

class AddViewController: UIViewController { 

    @IBOutlet weak var titleTextField: UITextField! 
    @IBOutlet weak var searchTextField: UITextField! 
    @IBOutlet weak var urlTextField: UITextField! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Do any additional setup after loading the view. 
    } 

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

    @IBAction func addButtonTapped(sender: AnyObject) { 
     var toAdd = PFObject(className:"Alert") 
     toAdd["title"] = titleTextField.text 
     toAdd["user_id"] = PFUser.currentUser() 
     toAdd["status"] = false 
     toAdd.saveInBackground() 
     self.navigationController?.popToRootViewControllerAnimated(true) 
    } 

    /* 
    // MARK: - Navigation 

    // In a storyboard-based application, you will often want to do a little preparation before navigation 
    override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { 
     // Get the new view controller using segue.destinationViewController. 
     // Pass the selected object to the new view controller. 
    } 
    */ 

} 

回答

0

也許您可以打開和關閉用戶交互,直到數據被接收並重新加載?

self.tableView.userInteractionEnabled = false 

也動self.loadData()viewDidLoad你不需要每次回去

+0

時間這是一個想法,重新下載,但我敢肯定有更好的事情要做......我聽說過異步加載,那是什麼?另外,如果我嘗試你的解決方案,我怎麼知道數據是否被接收? – user2178964 2014-10-17 19:37:18

+0

你不是在異步下載數據嗎?它只是意味着你開始一個後臺線程來下載數據,這種方式你不會阻止UI線程。 當發生這種情況時,它會顯示一條消息,例如「加載數據...」,然後一旦完成重新加載並允許交互 – meda 2014-10-17 19:40:34

+0

是的,實際上它已經是異步的了。我怎樣才能等待數據加載顯示單元格列表? – user2178964 2014-10-17 19:50:17

相關問題