2016-04-25 51 views
0

我試圖在iOS中實現多選表格視圖。它是如何工作的:無法在tableview中取消選擇第一個選定的單元格

每個項目的左邊都有一個複選框。 當用戶點擊此複選框時,tableview切換到多選模式。 用戶現在可以通過點擊複選框或單元格中的任何位置來選擇其他項目。這一切都工作正常保存1件事:

說我有3項在我的名單:A,B和C按字母順序排列。我點擊A的複選框進入多選模式並繼續添加B和C.如果我再次點擊B或C,則取消選中該項目,並且它們各自的複選框會再次被取消選中。如果我在取消選擇B和C之前嘗試取消選擇A,則該單元看起來仍處於選中狀態。然而,A會從我選擇的項目中移除。這通常發生在我用來進入多選模式的項目中。

我的代碼:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyNotificationTableViewCell 
    let notification = fetchedResultsController.objectAtIndexPath(indexPath) as! MyNotification 

    if(tableView.allowsMultipleSelection){ 
     if(!selectedNotificationsArray.containsObject(notification.notification_id)){ 
      tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None) 
      selectedNotificationsArray.addObject(notification.notification_id) 
      cell.selectionButton.imageView?.image = UIImage(named: "CheckboxChecked") 
     } 
    }else{ 
     tableView.deselectRowAtIndexPath(indexPath, animated: false) 
     let alert = UIAlertView(
      title: notification.scope, 
      message: notification.message, 
      delegate: self, 
      cancelButtonTitle: LocalizedString("cancel"), 
      otherButtonTitles: LocalizedString("alert_option_mark_as_read") 
     ) 
     alert.tag = 1 
     selectedNotificationsArray.addObject(notification.notification_id) 
     alert.show() 
    } 

    cell.setNeedsDisplay() 
} 

func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) { 
    if (buttonIndex == 1) { 
     markSelectedNotificationsAsRead() 
    }else{ 
     selectedNotificationsArray.removeAllObjects() 
    } 
} 

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { 
    print("deselected a cell") 

    let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyNotificationTableViewCell 
    let notification = fetchedResultsController.objectAtIndexPath(indexPath) as! MyNotification 

    if(selectedNotificationsArray.containsObject(notification.notification_id)){ 
     selectedNotificationsArray.removeObject(notification.notification_id) 
     tableView.deselectRowAtIndexPath(indexPath, animated: false) 
     cell.selectionButton.imageView?.image = UIImage(named: "CheckboxUnchecked") 
     if(selectedNotificationsArray.count == 0){ 
      switchNavigationBarMode(false) 
      tableView.reloadData() 
     } 
    } 
} 

func tappedSelectionCheckbox(sender: CheckBoxButton){ 
    let notification = fetchedResultsController.objectAtIndexPath(sender.cellIndexPath!) as! MyNotification 
    print("tapped checkbox of notification with message: " + String(notification.message)) 
    if(tableView.allowsMultipleSelection == false){ 
     switchNavigationBarMode(true) 
    } 
    if(selectedNotificationsArray.containsObject(notification.notification_id)){ 
     tableView(tableView, didDeselectRowAtIndexPath: sender.cellIndexPath!) 
    }else{ 
     tableView(tableView, didSelectRowAtIndexPath: sender.cellIndexPath!) 
    } 
    //Redraw cell so that the checkbox is updated 
    tableView(tableView, cellForRowAtIndexPath: sender.cellIndexPath!).setNeedsDisplay() 
} 

func switchNavigationBarMode(enabled: Bool){ 
    if(enabled){ 
     tableView.allowsMultipleSelection = true 
     backButton = self.navigationItem.leftBarButtonItem 
     self.navigationItem.setLeftBarButtonItem(selectAllButton, animated: true) 
     self.navigationItem.setRightBarButtonItems([markReadButton!, deleteButton!], animated: true) 
     self.navigationItem.title = nil 
    }else{ 
     tableView.allowsMultipleSelection = false 
     self.navigationItem.title = "Notifications" 
     self.navigationItem.setLeftBarButtonItem(backButton, animated: true) 
     self.navigationItem.setRightBarButtonItems(nil, animated: true) 
    } 
} 

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! MyNotificationTableViewCell 
    let notification = fetchedResultsController.objectAtIndexPath(indexPath) as! MyNotification 
    cell.messageLabel.text = notification.message 

    // Unread notifications are bold 
    if(notification.read_date.isEmpty){ 
     cell.messageLabel.font = UIFont(name: "TrebuchetMS-Bold", size: 17) 
    } 

    if(selectedNotificationsArray.containsObject(notification.notification_id)){ 
     tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: UITableViewScrollPosition.None) 
     cell.selectionButton.imageView?.image = UIImage(named: "CheckboxChecked") 

    }else{ 
     tableView.deselectRowAtIndexPath(indexPath, animated: true) 
     cell.selectionButton.imageView?.image = UIImage(named: "CheckboxUnchecked") 
    } 
    cell.selectionButton.cellIndexPath = indexPath 
    cell.selectionButton.addTarget(self, action: #selector(MyNotificationViewController.tappedSelectionCheckbox(_:)), forControlEvents: UIControlEvents.TouchUpInside) 

    let dateFormatter = NSDateFormatter() 
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.S'Z'" 
    let utcDateTimeObject = dateFormatter.dateFromString(notification.send_date) 
    dateFormatter.dateFormat = "HH:mm" 
    let shortTimestamp = dateFormatter.stringFromDate(utcDateTimeObject!) 
    cell.timestampLabel.text = shortTimestamp 
    let scope = notification.scope 
    switch(scope){ 
    case Constants.NOTIFICATION_SCOPE_DEVICE: 

     break 
    case Constants.NOTIFICATION_SCOPE_INVENTORY: 

     break 
    case Constants.NOTIFICATION_SCOPE_JOURNAL: 

     break 
    case Constants.NOTIFICATION_SCOPE_PROTOCOL: 

     break 
    case Constants.NOTIFICATION_SCOPE_SUPPLIES: 

     break 
    case Constants.NOTIFICATION_SCOPE_SYSTEM: 

     break 
    default: 
     break 
    } 
    return cell 
} 

回答

0

您在didSelectRowAtIndexPath方法調用tableView.selectRowAtIndexPath。我希望這會導致一些錯誤的行爲。

我會建議一個不同的更簡單的方法。如果你使用UITableViewCellAccessoryCheckmark來顯示你選擇的單元格,cellForRowAtIndexPath可以檢查A,B,C等是否在你的數據數組中,並在那裏選擇並添加選中標記。然後,你只需要在didDeselectRowAtIndexPath內調用reloadData,它更清晰。

這會稍微改變你的用戶界面,所以如果你嚴格地希望使用灰色選定的樣式單元格,這將不起作用,但問題似乎是在didDeselectRowAtIndexPath中調用selectRowAtIndexPath。你應該找到另一種方法來選擇單元格。

+0

「你可以在didDeselectRowAtIndexPath中調用tableView.selectRowAtIndexPath,我期望這會導致一些錯誤行爲。」 我做...?你的意思是說我隱式地稱它?因爲我的didDeselectRowAtIndexPath沒有直接調用selectRowAtIndexPath。 – Anubis

+0

看起來像你在第7行調用它。 –

+0

但是,這是在didSelectRowAtIndexPath方法,而不是您在答案中提到的didDeselectRowAtIndexPath方法。 – Anubis

相關問題