2016-03-27 25 views
0

この問題についていくつか質問があります。私はすべての提案された答えを試しましたが、まだ何も働いていません。 私はこれを持っていますfuncは、ユーザーが受け取る提供を断る。私は*****私は、ボタンのタグ値にdeleteRowsAtIndexPathsを複数回呼び出す

offerCell.declineButton.tag = indexPath.row 
offerCell.declineButton.addTarget(self, action: #selector(OpenDealsDetailsViewController.declineButtonTapped(_:)), forControlEvents: UIControlEvents.TouchUpInside) 

を割り当てる申し出を拒否し、セルの行を削除しても残された唯一の1セルがあるとき、私はcellForRowAtIndexPathfatal error: Index out of range

func declineButtonTapped(sender: AnyObject) { 
    self.view.userInteractionEnabled = false 
    let buttonRow = sender.tag // this is the tag from my custom cell button 
    let offer = offers[buttonRow] // I get the error here 
    let loadingNotification = MBProgressHUD.showHUDAddedTo(self.view, animated: true) 
    loadingNotification.mode = MBProgressHUDMode.Indeterminate 
    loadingNotification.labelText = "declining offer...." 
    let myUrl = NSURL(string: "\(ipAddress)/api/v1.0/offers.php") 
    let request = NSMutableURLRequest(URL: myUrl!) 
    request.HTTPMethod = "POST" 
    let postString = "id=\(offer.id!)&action=decline&offer_id=\(offer.offer_id!)" 
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true) 
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) 
     { data, response, error in 

      if error != nil { 

       let messageToDisplay = error      
       self.view.userInteractionEnabled = true 

       return 

      } 


      do{ 
       let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary 

       if let parseJSON = json{ 

        let resultValue = parseJSON["status"] as? String 

         if resultValue == "Success"{ 


          dispatch_async(dispatch_get_main_queue()) { 

          print("before count is \(self.offers.count)") // before the error the count is 2 here 
          self.offers.removeAtIndex(buttonRow) //update my model 
          self.tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: buttonRow, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade) 
          print("after count is \(self.offers.count)") //then the count is 1 here  
          MBProgressHUD.hideAllHUDsForView(self.view, animated: true) 

          self.view.userInteractionEnabled = true 

         } 


        }else{ 

         //no success  
       } 
      } 


     } catch{ 

     } 

    } 

    task.resume() 

} 

を得ることができます*更新*****

私はエラーが見つかりました。私が印刷するとき print("button row is\(buttonRow)")番号は更新されません。だから、最初の時間は、それが正しい行を呼び出しますが、私は

self.offers.removeAtIndex(buttonRow)         
self.tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: buttonRow, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Fade) 
self.tableView.reloadData() 

に私をしようとする場合declineButtonTapped

button row is0 before count is 2 after count is 1 button row is1 // this of course should be 0 as there is only one cell left fatal error: Index out of range

初めて呼ばれたとき、それは持っていた、それはindexPath.rowを保つ第二回次のエラーを取得する:

あなたがタグを使用するか、またはあなたべきではありませんどちらか

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

+0

カスタムセルに割り当てられているタグの値は何ですか? –

答えて

1

変更するたびにテーブルビューを完全に再ロードする必要があります。あるいは、可視のセルを反復してタグ値を更新することもできます。

テーブルから最後の行だけを削除する場合は、問題ありません。前の行を削除するとすぐに、それ以降のすべての行が不正なタグ値になります。したがって、最後の行に移動すると、そのタグには実際には存在せず、無効な行があれば、サーバーから間違った項目が削除されます。

より良い方法は、セルを削除してアクションを実行できるクラスのインスタンスに渡し、更新の詳細を表示コントローラにコールバックすることです。ビューコントローラは、そのデータソースとテーブルビューを更新できます。このようにして、テーブル索引パスとデータを取るアクションを分離します。

+0

もちろん、私が 'reloadData'で' deleteRowsAtIndexPaths'を変更した場合、私は上記のエラーは出ませんが、最初は好きです。最後に提案したオプションについて説明できますか?あなたは正しい方向へ私を向けることができますか? – mat

+0

あなたがタグを使用している理由は、それがシンプルに見えるということです。私が提案している他の解決方法は説明が複雑で難しいです。最初の実行として、データオブジェクトをセルに渡し、セルからデリゲートをコントローラに設定して、ボタンがタップされたときにデータオブジェクトを渡すことができます。次に、VCはそのデータ項目の正しい現在のインデックスパスを見つけることができます。私の主な命題はそれに似ていますが、別のクラスを使ってコードを分けています。 – Wain

+0

ありがとう。だから基本的には、どちらかのセルを削除するたびにテーブルがリロードされるようにreloadData()を使うか、より複雑なアプローチを使用する必要があります。これをMVPにすれば、私は簡単な解決策に行くと思います。 ;) – mat

関連する問題