无法在tableview中取消选择第一个选定的单元格

时间:2016-04-25 12:24:02

标签: ios uitableview checkbox multi-select

我正在尝试在iOS中实现多选表视图。工作原理:

每个项目左侧都有一个复选框。 当用户点击此复选框时,tableview切换到多选模式。 用户现在可以通过点击复选框或单元格中的任意位置来选择其他项目。这一切都很好,除了一件事:

假设我的列表中有3个项目:A,B和C按字母顺序排序。我点击A的复选框进入多选模式,然后继续添加B和C.如果我再次点击B或C,则取消选择该项目,并再次取消选中它们各自的复选框。如果我在取消选择B和C之前尝试取消选择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
}

1 个答案:

答案 0 :(得分:0)

在didSelectRowAtIndexPath中调用tableView.selectRowAtIndexPath。我希望这会引起一些错误的行为。

我建议采用另一种更简单的方法。如果您使用UITableViewCellAccessoryCheckmark来显示您选择的单元格,则cellForRowAtIndexPath可以检查您的数据数组中是否有A,B,C等,并在那里进行选择并添加复选标记。然后你只需要在didDeselectRowAtIndexPath中调用reloadData,它更干净。

这稍微改变了你的UI,所以如果你真的希望使用灰色选择的样式单元格,这将不起作用,但问题似乎是在didDeselectRowAtIndexPath中调用selectRowAtIndexPath。您应该找到另一种选择单元格的方法。