I am confused a little bit about settings table view cell accessories.
I have fixed two sections in my table
What I
I would keep track of the data that should be checked and change the cell in tableView:didSelectRowAtIndexPath: and update which data is checked in tableView:cellForRowAtIndexPath: like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// do usual stuff here including getting the cell
// determine the data from the IndexPath.row
if (data == self.checkedData)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// determine the selected data from the IndexPath.row
if (data != self.checkedData) {
self.checkedData = data;
}
[tableView reloadData];
}
Declare one int variable named prev
and implement this method:-
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType==UITableViewCellAccessoryNone)
{
cell.accessoryType=UITableViewCellAccessoryCheckmark;
if (prev!=indexPath.row) {
cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prev inSection:0]];
cell.accessoryType=UITableViewCellAccessoryNone;
prev=indexPath.row;
}
}
else{
cell.accessoryType=UITableViewCellAccessoryNone;
}
}
In Swift 2.0 using custom accessoryView uitableviewcell with swift
1º Creating Globar var IndexPath
var indexSelected = NSIndexPath()
2º In didSelectRowAtIndexPath
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
indexSelected = indexPath
TB_Lojas.reloadData()
}
3º in cellForRowAtIndexPath:
if SelectedIndexPath == indexPath {
let img = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
img.image = UIImage(named: "check")
cell.accessoryView = img
}else{
let img = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
img.image = UIImage(named: "uncheck")
cell.accessoryView = img
}
}
BlackBerry's answer in Swift 3. UITableView with standard cells, selecting 0 or 1 cells.
private var previousSelection = NSIndexPath()
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let cell = tableView.cellForRow(at: indexPath)!
if cell.accessoryType == .none {
cell.accessoryType = .checkmark
selection = indexPath
if previousSelection == IndexPath() {
previousSelection = indexPath
} else if previousSelection != indexPath {
let previousCell = tableView.cellForRow(at: previousSelection)
previousCell?.accessoryType = .none
previousSelection = indexPath
}
} else if cell.accessoryType == .checkmark {
cell.accessoryType = .none
selection = IndexPath()
}
}
I known this question is quite old, but here is the Swift version based on Blackberry's response (which I've voted up by the way)
import UIKit
class PlacesViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {
var placesArray = NSMutableArray()
var previousCheckedIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
self.placesArray.addObject("Tandil")
self.placesArray.addObject("Balcarce")
self.placesArray.addObject("Mar del Plata")
self.tableView.rowHeight = UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.placesArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.placesArray.objectAtIndex(indexPath.row) as? String
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if (indexPath.row != previousCheckedIndex) {
var cell: UITableViewCell = self.tableView.cellForRowAtIndexPath(indexPath)!
if (cell.accessoryType == UITableViewCellAccessoryType.None) {
cell.accessoryType = UITableViewCellAccessoryType.Checkmark
if (previousCheckedIndex != indexPath.row) {
cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: previousCheckedIndex, inSection: 0))!
cell.accessoryType = UITableViewCellAccessoryType.None
previousCheckedIndex = indexPath.row
}
} else {
cell.accessoryType = UITableViewCellAccessoryType.None
}
tableView.reloadData()
}
}
}
Here's how I do it with static cells, and bypassing cellForRow
Create a var that stores the location of the "checked" cell.
NSInteger _checkedCell;
Then just implement willDisplayCell
and didSelectRow
methods like this.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (_checkedCell == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
_checkedCell = indexPath.row;
[self.tableView reloadData];
}