UITableView Checkmark ТОЛЬКО ОДИН Ряд за раз

Вы подумали бы, что это будет легко. С помощью этого кода я могу проверить несколько строк в таблице, но то, что я ХОЧУ, должен иметь только одну строку, проверенную за раз. Если пользователь выбирает другую строку, то я хочу, чтобы старая строка была просто АВТОМАТИЧЕСКИ снята. Не знаю, как это сделать. Здесь мой код:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

[tableView deselectRowAtIndexPath:indexPath animated:YES];


UITableViewCell *theCell = [tableView cellForRowAtIndexPath:indexPath];

if (theCell.accessoryType == UITableViewCellAccessoryNone) {
    theCell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    else if (theCell.accessoryType == UITableViewCellAccessoryCheckmark) {
    theCell.accessoryType = UITableViewCellAccessoryNone;
    }
}

Спасибо за любую помощь, которую вы можете предоставить!

Ответы

Ответ 1

Лучший способ - установить тип аксессуара в cellForRowAtIndexPath и использовать didSelectRowAtIndexPath только для записи того, какой путь должен быть выбран, а затем вызвать reloadData.

Ответ 2

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
{
     [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}

Swift версия будет:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
}

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None
}

Swift 3 обновление:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath)?.accessoryType = .none
}

Swift 5 обновление

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath)?.accessoryType = .none
}

Ответ 3

Вы можете создать новую переменную для отслеживания индекса, выбранного в файле didSelectRowAtIndex.

int selectedIndex;

в вашем cellForRowAtIndexPath

if(indexPath.row == selectedIndex)
{
   cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
   cell.accessoryType = UITableViewCellAccessoryNone;
}

и в вашем файле didSelectRowAtIndex

selectedIndex = indexPath.row;
[tableView reloadData];

Ответ 4

Вам не нужно (и не следует) просто перезагружать таблицу после каждого выбора.

Apple имеет хороший documentation о том, как управлять списком выбора. См. Листинг 6-3 для примера.

Это более или менее тот же ответ, что и некоторые другие, но я подумал, что добавлю немного больше деталей.

Что вы хотите сделать, это сохранить текущую выбранную IndexPath для переменной и использовать ее в didSelectRowAtIndexPath для удаления старой галочки. Это также означает, что вы добавите новый флажок.

Вам нужно также установить/отключить галочки в cellForRowAtIndexPath, иначе если ваш список будет большим, а ячейки будут повторно использованы, это будет выглядеть как несколько строк. Это проблема с некоторыми другими ответами.

См. пример swift 2.0 ниже:

// for saving currently seletcted index path
var selectedIndexPath: NSIndexPath? = NSIndexPath(forRow: 0, inSection: 0)  // you wouldn't normally initialize it here, this is just so this code snip works
// likely you would set this during cellForRowAtIndexPath when you dequeue the cell that matches a saved user selection or the default

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    // this gets rid of the grey row selection.  You can add the delegate didDeselectRowAtIndexPath if you want something to happen on deselection
    tableView.deselectRowAtIndexPath(indexPath, animated: true) // animated to true makes the grey fade out, set to false for it to immediately go away

    // if they are selecting the same row again, there is nothing to do, just keep it checked
    if indexPath == selectedIndexPath {
        return
    }

    // toggle old one off and the new one on
    let newCell = tableView.cellForRowAtIndexPath(indexPath)
    if newCell?.accessoryType == UITableViewCellAccessoryType.None {
        newCell?.accessoryType = UITableViewCellAccessoryType.Checkmark
    }
    let oldCell = tableView.cellForRowAtIndexPath(selectedIndexPath!)
    if oldCell?.accessoryType == UITableViewCellAccessoryType.Checkmark {
        oldCell?.accessoryType = UITableViewCellAccessoryType.None
    }

    selectedIndexPath = indexPath  // save the selected index path

    // do whatever else you need to do upon a new selection
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
    // if this is the currently selected indexPath, set the checkmark, otherwise remove it
    if indexPath == selectedIndexPath {
        cell.accessoryType = UITableViewCellAccessoryType.Checkmark
    } else {
        cell.accessoryType = UITableViewCellAccessoryType.None
    }
}

Ответ 5

Вам не нужно перезагружать tableView.

Смотрите приведенный ниже код:

Объявить переменную NSIndexPath lastSelectedIndexPath для вашего класса

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if(lastSelectedIndexPath) {

        UITableViewCell *lastCell = [tableView cellForRowAtIndexPath:lastSelectedIndexPath];
        [lastCell setAccessoryView:nil];
    }

    UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:currentIndexPath];
    [currentCell setAccessoryView:UITableViewCellAccessoryCheckmark];

    lastSelectedIndexPath = indexPath;
}

Ответ 6

Я думаю, fooobar.com/questions/146309/... поможет вам.
Я использовал его, и он работает с deselectRowAtIndexPath тоже!

Ответ 7

Самый простой способ - сохранить выбранный IndexPath и проверить его в cellForRowAtIndexPath.

прилагается код:

шаг 1: инициализировать selectedIndexPath selectedIndexPath = [[NSIndexPath alloc] init];

шаг 2: в cellForRowAtIndexPath

if([selectedIndexPath isEqual:indexPath]){
    [checkMark setHidden:NO];
} else {
    [checkMark setHidden:YES];
}

Шаг 3: В файле didSelectRowAtIndexPath

selectedIndexPath = indexPath;
[tableView reloadData];

Он должен работать, попробуйте Njoy:)

Ответ 8

Для Swift 3 у меня работали следующие:

override func viewDidLoad() {
    super.viewDidLoad()

    // allow cells to be selected
    tableView.allowsSelection = true

    // ensure that deselect is called on all other cells when a cell is selected
    tableView.allowsMultipleSelection = false
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    tableVIew.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none
}

Ответ 9

Попробуйте следующее:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.section == 1 {
        // un-select the older row
        if let selected = self.LastSelected {
            tableView.cellForRowAtIndexPath(selected)?.accessoryType = .None
        }

        // select the new row
        tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = UITableViewCellAccessoryType.Checkmark
        self.LastSelected = indexPath
    }
}

Ответ 10

В Swift следующие работы отлично:

lastSelectedIndexPath = NSIndexPath(forRow: 1, inSection: 0)//Row will be the previous selected row


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell:LabelsSelectionCell = tableView.dequeueReusableCellWithIdentifier("LabelsSelectionCell", forIndexPath: indexPath) as! LabelsSelectionCell
    cell.setCellLael(labelOptionsArray[indexPath.row])
    if lastSelectedIndexPath == indexPath
    {
        cell.setCellCheckedStatus(true)
    }
    return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
    if let _ = lastSelectedIndexPath
    {
        let lastCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath!) as! LabelsSelectionCell
        lastCell.setCellCheckedStatus(false)
    }
    let currentCell:LabelsSelectionCell = tableView.cellForRowAtIndexPath(indexPath) as! LabelsSelectionCell
    currentCell.setCellCheckedStatus(true)

    lastSelectedIndexPath = indexPath

    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

Ответ 11

Swift iOS

     var checkedIndexPath : NSIndexPath?

     // table row which row was selected
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)

        println("Section #\(indexPath.section)! You selected cell #\(indexPath.row)!")

        if (self.checkedIndexPath != nil) {
            var cell = tableView.cellForRowAtIndexPath(self.checkedIndexPath!)
            cell?.accessoryType = .None
        }

        var cell = tableView.cellForRowAtIndexPath(indexPath)
        cell?.accessoryType = .Checkmark

        self.checkedIndexPath = indexPath

    }// end tableView

Ответ 12

В Swift 2.0 я использовал это:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    if((lastSelectedIndexPath) != nil) {
        let lastCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath)
        lastCell?.accessoryType = UITableViewCellAccessoryType.None
    }

    let currentCell = tableView.cellForRowAtIndexPath(indexPath)
    currentCell?.accessoryType = UITableViewCellAccessoryType.Checkmark

    lastSelectedIndexPath = indexPath

}

Ответ 13

Мой способ отменить выбор других ячеек при выборе:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = ....

    if condition {
        cell.accessoryType = .checkmark
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.bottom)
    } else {
        cell.accessoryType = .none
    }

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    for row in 0...tableView.numberOfRows(inSection: 0) {
        if row == indexPath.row {continue}
        tableView.deselectRow(at: IndexPath(row: row, section: 0), animated: true)
    }

    if let cell = tableView.cellForRow(at: indexPath) {
        cell.accessoryType = .checkmark
    }
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)
    cell?.accessoryType = .none
}

Ответ 14

Вот что я придумал, когда у меня возникла эта проблема.
Этот код реализован в последней версии Swift, на сегодняшний день...
Для получения дополнительной информации и/или файла расширения, пожалуйста, ознакомьтесь с Github Gist этого фрагмента.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {       
    if let sip = selectedIndex {
        tableView.deselectRow(at: sip, animated: false)
    }
    selectedIndex = indexPath
}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    if selectedIndex?.row == indexPath.row {
        selectedIndex = nil
    }
}

Ответ 15

проверено и решено попробовать, чтобы он работал отлично

добавить это как глобальную переменную

var selectedIndexPath = NSIndexPath(row: 0, section: 0)

Добавьте это в метод didselect

        // old one check off
        if indexPath != selectedIndexPath as IndexPath {
            let oldCell = categorytable.cellForRow(at: selectedIndexPath as IndexPath)
            if oldCell?.accessoryView != nil {
                oldCell?.accessoryView = nil
            }
            else {
                let imageName = "checkmark"
                let image: UIImageView = UIImageView(image: UIImage(named: imageName))
                cell.accessoryView = image
            }
        }
        // the new one on

        if  cell.accessoryView == nil {
            let imageName = "checkmark"
            let image: UIImageView = UIImageView(image: UIImage(named: imageName))
            cell.accessoryView = image
        }
        else {
            cell.accessoryView = nil
        }

Ответ 16

Вы можете сделать это в пользовательском типе ячейки в одной строке кода.

final class CheckableTableViewCell: UITableViewCell {

  override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    self.accessoryType = selected ? .checkmark : .none
  }

}

Чтобы этот метод работал, нужно выбрать ячейку.

Если вы не хотите видеть выделение выделенной ячейки, просто установите для параметра selectionStyle ячейки значение .none в раскадровке или в коде

Этот метод не будет работать, если вы будете вызывать

tableView.deselectRow(at: indexPath, animated: true)

Также отлично работает с множественным выбором.