2016-03-27 20 views
0

Bu sorun hakkında birçok soru var. Tüm önerilen cevapları denedim ama henüz hiçbir şey işe yaramadı. Yani, bir kullanıcının aldığı teklifleri reddeden bu func var. Ben ***** teklifleri reddetme ve hücre satırları silmek ama sadece olduğunda bir hücre ben düğmeçağrı deleteRowsAtIndexBir kez birden çok kez geçirme

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

etiket değeri atamak cellForRowAtIndexPath içimde fatal 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() 

} 

olsun sol edebilirsiniz * GÜNCELLEME *****

Sanırım hatayı buldum. print("button row is\(buttonRow)")'u yazdırdığımda sayı güncellenmez. Böylece ilk kez declineButtonTapped denirdi buna vardı indexPath.row tutmak doğru satır ama ikinci kez ilk kez çağırır

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

Ben

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

I yapmaya çalışırsanız

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

Özel hücrenize atanan etiket değeri nedir? –

cevap

1

ya etiketleri veya sizi kullanmamalısınız: aşağıdaki hatayı alıyorum Her değişiklikten sonra tablo görünümünü tamamen yeniden yüklemelidir. Alternatif olarak görünen hücreleri yineleyebilir ve etiket değerlerini güncelleyebilirsiniz.

Her zaman ve sadece son satırı tablodan silerseniz, bu iyi olurdu. Daha önceki bir satırı sildiğiniz anda tüm satırlar bundan sonra yanlış bir etiket değerine sahip olur. Bu nedenle, son satıra gittiğinizde bu etikette bulunmaz ve diğer geçersiz satırlar, yanlış öğeyi sunucudan silmenize neden olur.

Daha iyi bir yaklaşım, hücreyi silme işlemini gerçekleştirebilen ve yapılan güncelleştirmenin ayrıntıları ile birlikte görünüm denetleyicisine geri dönebilen bir sınıf örneğini iletmektir. Görünüm denetleyicisi daha sonra veri kaynağını ve tablo görünümünü güncelleyebilir. Bu şekilde tablo indeksi yolunu, verilere yapacağınız işlemden ayırırsınız.

+0

elbette 'deleteRowsAtIndexPaths' ile' reloadData' değiştirirseniz yukarıdaki hatayı alamıyorum ama ilkini tercih ederim. Önerdiğin son seçeneği açıklayabilir misin? lütfen beni doğru yöne yönlendirir misin? – mat

+0

etiketini kullanmanın sebebi basit görünmesi, önerdiğim diğer çözümün daha karmaşık ve açıklanması zor olmasıdır. İlk çalıştırma olarak veri nesnesini hücreye aktarabilir ve düğmeye dokunduğunda veri nesnesini geçen denetleyiciye hücreden bir temsilci kurabilirsiniz. Daha sonra VC, bu veri öğesi için doğru geçerli dizin yolunu bulabilir. Ana önerim buna benzer, ancak kodu daha iyi ayırmak için başka bir sınıf kullanıyor. – Wain

+0

Bunun için teşekkürler. Yani temel olarak, reloadData() yöntemini kullanıyorum, böylece bir hücreyi her sildikten sonra tablo yeniden yüklenir veya daha karmaşık bir yaklaşım kullanmam gerekir. Bu bir MVP olarak ben daha kolay çözüm için gideceğim düşünüyorum. ;) – mat

İlgili konular