accessory tick on uitableviewcell not showing in some instances - iphone

I have two tableviews, one has several tableview cells each cell opens the same subview but initalized with new data..
There are around about 100 - 200 entries into the table and I have a accessory view that is a tick that when a cell is selected it ticks the cell then loads the main view again.
If I select that same cell to get the same dataset back it loads the previously selected cell in the middle of the screen (so it knows its index path) however the tick "depending on how deep in the list" will or will not be visible..
It tends to work in about the top 30/40% of the table but anything lower the tick will not be visible... that is unless I go back and forth getting deeper and deeper each time then sometimes I can get the tick to appear in the deeper part of the tableview.. Would anyone know why this is happening?
Has anyone had something of this nature happen to them before?
At further investigation I think something is going wrong inside this method..
First of all, in the subview once the user selects a cell this method is called
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
[self.navigationController popViewControllerAnimated:YES]; //pops current view from the navigatoin stack
//accesses selected cells content
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// now you can use cell.textLabel.text
//This if statment is based off which cell was selected in the parent view so that it knows which cell to pass the data back to
if (parentViewSelectedIndexPath.section == 0) {
if (parentViewSelectedIndexPath.row == 0) {
manufactureCellTextLabel = cell.textLabel.text; //passing label text over to NSString for use with delegate (check "viewwilldissapear")
[[self delegate] setManufactureSearchFields:manufactureCellTextLabel withIndexPath:indexPath]; //This is where I pass the value back to the mainview
}
// a few more If statements for the other methods I can pass data too.
//--- this if block allows only one cell selection at a time
if (oldCheckedData == nil) { // No selection made yet
oldCheckedData = indexPath;
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else {
UITableViewCell *formerSelectedcell = [tableView cellForRowAtIndexPath:oldCheckedData]; // finding the already selected cell
[formerSelectedcell setAccessoryType:UITableViewCellAccessoryNone];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark]; // 'select' the new cell
oldCheckedData = indexPath;
}
}
This passes Index path over to the main view method...
- (void) setManufactureSearchFields:(NSString *)cellLabeltext withIndexPath:(NSIndexPath *)myIndexPath
{
manufactureSearchObjectString = cellLabeltext;
manufactureResultIndexPath = myIndexPath;
[self.tableView reloadData]; //reloads the tabels so you can see the value.
}
//Which then sets the manufactureResultIndexPath that is used in the next method to pass it back to the subview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
//--- Idendify selected indexPath (section/row)
if (indexPath.section == 0) {
//--- Get the subview ready for use
VehicleResultViewController *vehicleResultViewController = [[VehicleResultViewController alloc] initWithNibName:#"VehicleResultViewController" bundle:nil];
// ...
//--- Sets the back button for the new view that loads
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style: UIBarButtonItemStyleBordered target:nil action:nil] autorelease];
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:vehicleResultViewController animated:YES];
[vehicleResultViewController setDelegate:self];
if (indexPath.row == 0)
{
vehicleResultViewController.title = #"Manufacture";
[vehicleResultViewController setRequestString:#"ID.xml"]; //sets the request string in searchResultsViewController
vehicleResultViewController.dataSetToParse = #"ID"; // This is used to controll what data is shown on subview... logic
[vehicleResultViewController setAccessoryIndexPath:manufactureResultIndexPath]; //sends indexpath back to subview for accessory tick
vehicleResultViewController.parentViewSelectedIndexPath = indexPath;
}
//etc etc
}
And finaly I pass it to the method in my subview that passes the indexpath to oldCheckedData
- (void)setAccessoryIndexPath:(NSIndexPath *)myLastIndexPath
{
oldCheckedData = myLastIndexPath;
[self.tableView reloadData]; //<<---- this is where I reload the table to show the tick...
}

Try moving the cell.accessoryType = lines to the willDisplayCell: delegate function like so:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
// You can move this one here too:
cell.selectionStyle = UITableViewCellSelectionStyleNone; // no blue selection
if (indexPath == oldCheckedData) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
I read that the willDisplayCell: method should be used for any basic visual related modifications to a cell like selectionStyle/accessoryType, and the cellForRowAtIndexPath: method for cell data related operations like setting text, images, etc...

I have recently come across this issue, if turned out the in my case the cell has a accessoryview set. This snippet withh ensure the view is removed.
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
..logic here to to determine if cell should be selected...
if ( cell.accessoryView != nil) {
cell.accessoryView?.removeFromSuperview()
cell.accessoryView = nil
}
cell.accessoryType = .checkmark

Related

UITableViewCell background disappears?

The UITableViewController in my app pulls data from a json data source. I have also created a custom UITableViewCell background using CG. There is a very interesting bug that happens and I have no idea why. I will walk you through what happens and how I recreate it:
Tap to enter table view.
Without scrolling the table at all I immediately tap on an item in view.
After tapping on that item I press the back button to return to the table view.
If I then scroll down the first cell to appear from off screen will not have my custom back ground. It will just be the default for a cell. Then if I continue to scroll down every 10th cell will have the same issue.
This bug only occurs in this exact process. If I were to scroll the table view at all before tapping on an item it would not happen.
Here is the relevant code for the tableview controller:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Will remove all of the used codes from the table if setting is enabled
if (self.shouldHideCodes) {
NSMutableArray *tempArray = [self.jsonCodeData mutableCopy];
[tempArray removeObjectsInArray:[self.usedCodes usedCodes]];
self.jsonCodeData = tempArray;
}
return [self.jsonCodeData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if (self.jsonCodeData) {
cell = [tableView dequeueReusableCellWithIdentifier:#"code cell"];
if ([cell isKindOfClass:[CodeCellTVC class]]) {
CodeCellTVC *tvcCell = (CodeCellTVC *)cell;
if (![tvcCell.backgroundView isKindOfClass:[CustomCellBackground class]]) {
tvcCell.backgroundView = [[CustomCellBackground alloc] init];
}
NSDictionary *codeDict = [self.jsonCodeData objectAtIndex:indexPath.row];
// Retrieve code string from dictionary
NSString *codeText = [NSString stringWithFormat:#"%#", [codeDict objectForKey:#"code"]];
tvcCell.codeTableLabel.text = codeText;
}
}
return cell;
}
The thing that confuses me is how it reacts. That when the bug happens every 10th cell has the issue and not every one. I don't have anything outside of these method's that deal with the tableviewcell itself.
I understood your problem, you did a wrong at the time of initializing the cell,Every time your intializing the cell, so that every time memory will allocate for that cell, it will create memory issue.
Edit the code like bellow it will work for you.
cell = [tableView dequeueReusableCellWithIdentifier:#"code cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"code cell"];
}

How to display a custom UITableViewCellAccessoryCheckmark

I have a table view that needs a custom UITableViewCellAccessoryCheckmark. The checkmark displays when a row is selected and disappears when anther row is selected and then appears on the last most selected view. That works fine.
the problem arises when I use this line:
cell.accessoryView = [[ UIImageView alloc ]
initWithImage:[UIImage imageNamed:#"icon-tick.png" ]];
to add a custom UITableViewCellAccessoryCheckmark. After that code the UITableViewCellAccessoryCheckmark remain on all rows and don't disappear when another row is touched.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int index = indexPath.row; id obj = [listOfItems objectAtIndex:index];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSLog(#"%d",indexPath.row);
if (rowNO!=indexPath.row) {
rowNO=indexPath.row;
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;
cell.accessoryView = [[ UIImageView alloc ]
initWithImage:[UIImage imageNamed:#"icon-tick.png" ]];
[self.tableView cellForRowAtIndexPath:lastIndexPth].accessoryType=UITableViewCellAccessoryNone;
lastIndexPth=indexPath;
}
A much cleaner and cooler way would be to overwrite UITableViewCell like this:
- (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType
{
// Check for the checkmark
if (accessoryType == UITableViewCellAccessoryCheckmark)
{
// Add the image
self.accessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"YourImage.png"]] autorelease];
}
// We don't have to modify the accessory
else
{
[super setAccessoryType:accessoryType];
}
}
If you have done that, you can continue using UITableViewCellAccessoryCheckmark because your class will automatically replace it with an image.
You should only set the style in your cellForRowAtIndexPath method. Like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// [init subclassed cell here, dont forget to use the table view cache...]
cell.accessoryType = (rowNO != indexPath.row ? nil : UITableViewCellAccessoryCheckmark);
return cell;
}
And then, you just have to update rowNO in didSelectRowAtIndexPath to update your data and redraw the cell, like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (rowNO != indexPath.row)
{
rowNO = indexPath.row;
}
[self.tableView reloadData];
}
Also, instead of reloading the whole table with [self.tableView reloadData], you could only reload the two cells that change their style (e.g. checkmark) using reloadRowsAtIndexPaths.
Hm don't know why but i can't add comments so im writing this as answer. The problem with Blauesocke answer is that the AccessoryType wil be not set to UITableViewCellAccessoryCheckmark so you can't check the cell AccessoryType. Is there some way to do it right so the cell AccessoryType will be corect type just another image.
I'm using the method like this :
- (void)setAccessoryType:(UITableViewCellAccessoryType)newAccessoryType
{
[super setAccessoryType:newAccessoryType];
// Check for the checkmark
switch(newAccessoryType)
{
case UITableViewCellAccessoryCheckmark:
self.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"yorCheckmark.png"]];
break;
case UITableViewCellAccessoryNone:
self.accessoryView = nil;
break;
default:
break;
}
}

Not refreshing screen in programmatically filled TableView

When I scroll down and up again my text in tableView will disappear.
And my code is:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [screenDefBuild.elementsToTableView count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
ScreenListElements *currentScreenElement = [screenDefBuild.elementsToTableView objectAtIndex:indexPath.row];
cell.textLabel.text = currentScreenElement.objectName;
currentRow++;
return cell;
}
- (void)viewDidLoad
{
[super viewDidLoad];
tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[tableView setDataSource:self];
[self.view addSubview:tableView];
}
I also want to fill my table view to entire screen. (grey strap on the top).
I don't know what you're doing with this variable
currentRow++;
But whatever you use that for, i'd wager its breaking your code.
the UITableView will call cellForRowAtIndexPath every time a cell is about to appear on screen regardless of whether it has been on screen before or not. When you scroll down and then scroll back up this variable will have increased beyond the bounds of your data, hence you get empty cells.
You need to design this method in such a way that it can create any cell in the table view at any time. You can't rely on the order that the cells will be made and with scrolling you will have to make the same cell over and over again. Only use indexPath to figure out which cell you are currently supposed to be making.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html
Answer for the second part of the question- grey strap. You are adding the table view to current view, so you should use the size property of self.view.frame but not the origin. You want this to be set to 0,0.
Change
tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
to
CGRect viewFrame=self.view.frame;
viewFrame.origin=CGPointZero;
tableView = [[UITableView alloc] initWithFrame:viewFrame];
As for the first part of your question- it's strange, as you seem to do everything properly. One thing i may suggest is to add [tableView reloadData]; in the end of viewDidLoad.

UITableView Multiple Selection

How can I add a UITableView into my View-Based Application where the user will tap on more than one cell, and it will become selected, exactly like the Clock app's "New Alarm" setting named "Repeat" (Clock>Alarms> + >Repeat), and how can I get all of the selected cells in an array?
For multiple selection, add the line below in viewDidLoad()
tableView.allowsMultipleSelection = true
Configure each cell after dequeuing (or initializing) it in tableView(_:cellForRowAt:)
let selectedIndexPaths = tableView.indexPathsForSelectedRows
let rowIsSelected = selectedIndexPaths != nil && selectedIndexPaths!.contains(indexPath)
cell.accessoryType = rowIsSelected ? .checkmark : .none
// cell.accessoryView.hidden = !rowIsSelected // if using a custom image
Update each cell when it's selected/deselected
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)!
cell.accessoryType = .checkmark
// cell.accessoryView.hidden = false // if using a custom image
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)!
cell.accessoryType = .none
// cell.accessoryView.hidden = true // if using a custom image
}
When you're done, get an array of all the selected rows
let selectedRows = tableView.indexPathsForSelectedRows
and get the selected data, where dataArray maps to the rows of a table view with only 1 section
let selectedData = selectedRows?.map { dataArray[$0.row].ID }
In your implementation of -tableView:didSelectRowAtIndexPath: you would set the table view cell's accessoryType property depending on its current value (so it would toggle on and off with multiple taps). For example:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)path {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
You could either maintain an array of selected states in addition to the cells' own accessory type state, or iterate over the cells in the table view querying for each one's state in order to read out the selected rows.
#BrendanBreg implementation didn't worked for me. #RaphaelOliveira provided good solution, but when you scrolls your table down - wrong rows become selected (because UITableView caches it's cells). So, I've slightly modified Raphael's solution:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
/*Here is modified part*/
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
...
Your implementation stays here
we're just adding few lines to make sure
that only correct rows will be selected
*/
if([[tableView indexPathsForSelectedRows] containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
self.tableView.allowsMultipleSelection = YES;
Just a quick tip in addition to the great answer above: to mimic Apple's style from the clock app (making the row select color fade back out after checking / unchecking the row), add this to the didSelectRowAtIndexPath, after the conditionals:
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
From Apple's TableMultiSelect guide.
Here it is what you needed
http://developer.apple.com/library/ios/#samplecode/TableMultiSelect/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011189-Intro-DontLinkElementID_2
I have seen this problem with so many developers. Due to table view's nature of re-using cell it removes or haphazard the checks. I have created a working solution for that. Clone/download code from DevelopmentSupportWorkspace and Execute UITableViewTest project from there.
Here is code summery for that:
#interface CheckBoxTestTableViewController ()
#property (nonatomic, strong) NSArray *dataArray;
#property (nonatomic, strong) NSMutableDictionary *selectedIndexDictionary;
#end
#implementation CheckBoxTestTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//
_dataArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"ImageList" ofType:#"plist"]];
_selectedIndexDictionary = [NSMutableDictionary dictionary];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"checkMarkCell" forIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
// Configure the cell...
cell.textLabel.text = _dataArray[indexPath.row][#"text"];
if (_selectedIndexDictionary[indexPath] != nil) cell.accessoryType = UITableViewCellAccessoryCheckmark;
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
if (_selectedIndexDictionary[indexPath] == nil) {
[_selectedIndexDictionary setObject:_dataArray[indexPath.row] forKey:indexPath];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
}else{
[_selectedIndexDictionary removeObjectForKey:indexPath];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
}
// [tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
#end
The clock alarms repeat table view is not multiple selection. Think of it as a lit of checkboxes.
When a cell is selected, the font color and accessory type are changed and the selection fades out. When a checked cell is selected, the font color and accessory type are changed back and the selection fades out.
In your didSelectRowAtIndexPath delegate method, you would set the text color and accessory type for the selected cell, then deselect the cell. You would also record the new state in your data model. That could be as simple as a bit mask representing the selected state, but depends on what data you are displaying.
In your cellForRowAtIndexPath: dataSource method, set the text color and accessory type based on your data model.
Actual multiple selection would be similar. You have to keep track of which cells are selected, and set the selected cell of each state as it is created or shown. When the table view reports that a cell is selected, toggle the selection state in your data model and set the selected state of the cell accordingly.
You can't key off indexPath because the cells that refers to changes as you scoll. Put an NSLog in cellForRowAtIndexPath to see that. You can do the check/uncheck in willSelectRowAtIndexPath or didSelectRowAtIndexPath. That covers only the initial check or uncheck though, and will also have things appear as checked once you've scrolled because the underlying cell for a given indexPath changes.
So the solution I found is to have an array of selected things with something that is specific to that given cell, and do the initial check.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
if (![selectedIndexes containsObject:cell.textLabel.text]){
[selectedIndexes addObject:cell.textLabel.text];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
[selectedIndexes removeObject:cell.textLabel.text];
cell.accessoryType = UITableViewCellAccessoryNone;
}
return indexPath;
}
You also have to have logic in cellForRowAtIndexPath to make sure the right stuff is checked or not as the view scrolls:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
cell.accessoryType = UITableViewCellAccessoryNone;
if ([selectedIndexes containsObject:cell.textLabel.text]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[cell setSelected:YES animated:YES];
}
return cell;
}
1 - Allow multiple selection and toggle of selected state:
tableView.allowsMultipleSelection = true
2 - Collect or get an array of all selected indices when you are done:
let selected = tableView.indexPathsForSelectedRows
Note: This is independent of which cells are currently showing on screen.
3 - Change the appearance of the cell depending on selected state: Override this method in your UITableViewCell subclass. If you don't have a subclass, make one.
// In UITableViewCell subclass
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
accessoryType = selected ? .Checkmark : .None
}
I know that this is an old posting, but for future use, the following code will solve the problem of ensuring that a checkmark will only appear on selected rows during scrolling:
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.accessoryType = (cell.isSelected) ? .checkmark : .none
}

Selecting a default item when using UITableViewController as a checkbox list

In a lot of iPhone apps, I see a UITableViewController being used as a checkbox list. (See, for an example of what I mean, Auto-Lock under Settings)
While trying to implement this myself, I had to jump through a lot of hoops in order to have an item selected programmatically by default (ie., the current value for what the list represents). The best I've been able to come up with is by overriding the viewDidAppear method in my view controller class:
- (void)viewDidAppear:(BOOL)animated {
NSInteger row = 0;
// loop through my list of items to determine the row matching the current setting
for (NSString *item in statusItems) {
if ([item isEqualToString:currentStatus]) {
break;
}
++row;
}
// fetch the array of visible cells, get cell matching my row and set the
// accessory type
NSArray *arr = [self.tableView visibleCells];
NSIndexPath *ip = [self.tableView indexPathForCell:[arr objectAtIndex:row]];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:ip];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.lastIndexPath = ip;
[super viewDidAppear:animated];
}
Is this the best/only/easiest way to get a reference to a particular cell and indexPath if I want to mark a row by default?
In order to display the status items, you have to implement tableView:cellForRowAtIndexPath: anyway, don't you? So, why not just set the accessory type of the cell before returning the cell, like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// dequeue or create cell as usual
// get the status item (assuming you have a statusItems array, which appears in your sample code)
NSString* statusItem = [statusItems objectAtIndex:indexPath.row];
cell.text = statusItem;
// set the appropriate accessory type
if([statusItem isEqualToString:currentStatus]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
Your code is extremely fragile, especially because you use [self.tableView visibleCells]. What if there are more status items than rows fitting on the screen (as the name suggests, visibleCells only returns the currently visible cells of the table view)?