Ответ 1
Лучший способ - установить тип аксессуара в cellForRowAtIndexPath и использовать didSelectRowAtIndexPath только для записи того, какой путь должен быть выбран, а затем вызвать reloadData.
Вы подумали бы, что это будет легко. С помощью этого кода я могу проверить несколько строк в таблице, но то, что я ХОЧУ, должен иметь только одну строку, проверенную за раз. Если пользователь выбирает другую строку, то я хочу, чтобы старая строка была просто АВТОМАТИЧЕСКИ снята. Не знаю, как это сделать. Здесь мой код:
- (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;
}
}
Спасибо за любую помощь, которую вы можете предоставить!
Лучший способ - установить тип аксессуара в cellForRowAtIndexPath и использовать didSelectRowAtIndexPath только для записи того, какой путь должен быть выбран, а затем вызвать reloadData.
- (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
}
Вы можете создать новую переменную для отслеживания индекса, выбранного в файле didSelectRowAtIndex.
int selectedIndex;
в вашем cellForRowAtIndexPath
if(indexPath.row == selectedIndex)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
и в вашем файле didSelectRowAtIndex
selectedIndex = indexPath.row;
[tableView reloadData];
Вам не нужно (и не следует) просто перезагружать таблицу после каждого выбора.
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
}
}
Вам не нужно перезагружать 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;
}
Я думаю, fooobar.com/questions/146309/... поможет вам.
Я использовал его, и он работает с deselectRowAtIndexPath тоже!
Самый простой способ - сохранить выбранный 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:)
Для 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
}
Попробуйте следующее:
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
}
}
В 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)
}
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
В 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
}
Мой способ отменить выбор других ячеек при выборе:
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
}
Вот что я придумал, когда у меня возникла эта проблема.
Этот код реализован в последней версии 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
}
}
проверено и решено попробовать, чтобы он работал отлично
добавить это как глобальную переменную
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
}
Вы можете сделать это в пользовательском типе ячейки в одной строке кода.
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)
Также отлично работает с множественным выбором.