Switch That Checks Nsindexpath's Row and Section

switch that checks NSIndexPath's row and section

One way (this works because NSIndexPaths themselves are equatable):

switch indexPath {
case NSIndexPath(forRow: 0, inSection: 0) : // do something
// other possible cases
default : break
}

Or you could just test against integers, using a tuple pattern:

switch (indexPath.section, indexPath.row) {
case (0,0): // do something
// other cases
default : break
}

Another trick is to use switch true and the same condition you're already using:

switch true {
case indexPath.row == 0 && indexPath.section == 0 : // do something
// other cases
default : break
}

Personally, I would use nested switch statements where we test against indexPath.section on the outside and indexPath.row on the inside.

switch indexPath.section {
case 0:
switch indexPath.row {
case 0:
// do something
// other rows
default:break
}
// other sections (and _their_ rows)
default : break
}

UITableViewCell - check mark one row per section

you have an error with this

// uncheck all visible cells.

    for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}

Here the for loop deselect all the cell. you have to check also the section in if loop

you can set tag for your cell like this

 cell.tag = indexPath.section;

and in for loop if condition is

    for (UITableViewCell *cell in [aTableView visibleCells]) {
if (cell.accessoryType != UITableViewCellAccessoryNone && cell.tag == indexPath.section) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}

Set one check mark for each section in UITableView and save its state

I have found a precise and perfect solution,thanks to Lithu T.V and Nithin Gobel for guiding me in the right direction.Unfortunately their solutions didn't help me in achieving 1 check mark per section,but multiple check marks in fact.So I thought of saving the selected row in user defaults and for initially selecting 1st row of each section,we declare first and second section index,assign to index path and then assign cell accessory view as check mark.Here we go,let's first deal with cellForRowAtIndexPath:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.row,indexPath.section];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor whiteColor];
NSUserDefaults *savedState = [NSUserDefaults standardUserDefaults];

switch (indexPath.section)
{
case 0:
{
NSNumber *indexNumber = [NSNumber numberWithInteger:indexPath.row];
if([[savedState objectForKey:@"firstSectionIndex"] isEqual: indexNumber])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.firstSectionIndex = indexPath;
}

if (indexPath.row == 0)
{
NSObject * checkedCellObject = [savedState objectForKey:@"firstSectionIndex"];
if(checkedCellObject == nil)
{
self.firstSectionIndex = indexPath;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
cell.textLabel.text = @"Yes";
}
if (indexPath.row == 1)
{
cell.textLabel.text = @"No";
}
}
break;
case 1:
{
NSNumber *indexNumber = [NSNumber numberWithInteger:indexPath.row];
if([[savedState objectForKey:@"secondSectionIndex"] isEqual: indexNumber])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
secondSectionIndex = indexPath;
}

if (indexPath.row == 0)
{
NSObject * checkedCellObject = [savedState objectForKey:@"secondSectionIndex"];
if(checkedCellObject == nil)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
secondSectionIndex = indexPath;
}
cell.textLabel.text = @"Easy";
}
if (indexPath.row == 1)
{
cell.textLabel.text = @"Medium";
}
if (indexPath.row == 2)
{
cell.textLabel.text = @"Hard";
}
}
break;

default:
break;
}
}

tableView.backgroundColor = [UIColor clearColor];
tableView.backgroundView = nil;

return cell;
}

Please observe in each case,we are checking if the checked state is in saved user defaults,if it is nil,we check 1st cell(row) of each section,here we go with table view delegate method,did select row at index path:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];

if (indexPath.section == 0)
{
UITableViewCell *checkCell = [tableView cellForRowAtIndexPath:indexPath];
if(firstSectionIndex && firstSectionIndex != indexPath)
{
UITableViewCell *uncheckCell = [tableView cellForRowAtIndexPath:firstSectionIndex];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
self.firstSectionIndex = indexPath;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:firstSectionIndex.row] forKey:@"firstSectionIndex"];
checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
}

if (indexPath.section == 1)
{
UITableViewCell *checkCell = [tableView cellForRowAtIndexPath:indexPath];
if(secondSectionIndex)
{
UITableViewCell *unchekCell = [tableView cellForRowAtIndexPath:secondSectionIndex];
unchekCell.accessoryType = UITableViewCellAccessoryNone;
}
self.secondSectionIndex = indexPath;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:secondSectionIndex.row] forKey:@"secondSectionIndex"];
checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}

That's it,we have successfully accomplished one check mark per section and also save the accessory state of cell in user defaults for long term reference.

Hope this helps some one,thanks :)

UITableView select a row per section

This one's gonna be ViewController.h

@interface ViewController : UITableViewController
{
NSMutableArray *list;
NSMutableArray *sectionList;

NSIndexPath *oldIndexPath0;
int row0;
NSIndexPath *oldIndexPath1;
int row1;
NSIndexPath *oldIndexPath2;
int row2;
NSIndexPath *oldIndexPath3;
int row3;

NSString *othersString;
NSString *timeString;
NSString *pRoomString;
NSString *parkingString;
NSString *smokingString;

NSString *select0;
NSString *select1;
NSString *select2;
NSString *select3;
}
@end

This one's ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewWillAppear:(BOOL)animated
{
// initial row by 100;
row0 = 100;
row1 = 100;
row2 = 100;
row3 = 100;

// initial strings by @”"
othersString = [NSString stringWithFormat:@""];
timeString = [NSString stringWithFormat:@""];
pRoomString = [NSString stringWithFormat:@""];
parkingString = [NSString stringWithFormat:@""];
smokingString = [NSString stringWithFormat:@""];

select0 = @"";
select1 = @"";
select2 = @"";
select3 = @"";

// Get row index
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *fileName = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/rowString.txt"];
NSData *rowData = [fileManager contentsAtPath:fileName];
// From NSData to NSString
NSString *rowString = [[NSString alloc] initWithData:rowData encoding:NSUTF8StringEncoding];
if (rowString) {
// spit row string
NSArray *rowArray = [rowString componentsSeparatedByString:@":"];
for (int i=0; i<[rowArray count]; i++) {
NSString *indexVal = [rowArray objectAtIndex:i];
if ([indexVal length] != 0) {
// set row value
if (i == 0) {
NSString *row0Str = [rowArray objectAtIndex:0];
row0 = [row0Str intValue];
}
if (i == 1) {
NSString *row1Str = [rowArray objectAtIndex:1];
row1 = [row1Str intValue];
}
if (i == 2) {
NSString *row2Str = [rowArray objectAtIndex:2];
row2 = [row2Str intValue];
}
if (i == 3) {
NSString *row3Str = [rowArray objectAtIndex:3];
row3 = [row3Str intValue];
}
}
}
}
// Update the view with current data before it is displayed.
[super viewWillAppear:animated];

//Initialize the array.
list = [[NSMutableArray alloc] initWithCapacity:0];
sectionList = [[NSMutableArray alloc] initWithCapacity:0];

// section header
NSArray *sectionHeaderArray = [NSArray arrayWithObjects:@"01",@"02",@"03",@"04", nil];
NSDictionary *sectionHeaderDic = [NSDictionary dictionaryWithObject:sectionHeaderArray forKey:@"section"];
[sectionList addObject:sectionHeaderDic];
// time list
NSArray *timeArray = [NSArray arrayWithObjects:@"time 01",@"time 01",@"time 01", nil];
NSDictionary *timeDic = [NSDictionary dictionaryWithObject:timeArray forKey:@"time"];
// private room
NSArray *pRoomArray = [NSArray arrayWithObjects:@"room 01",@"room 02", nil];
NSDictionary *pRoomDic = [NSDictionary dictionaryWithObject:pRoomArray forKey:@"pRoom"];
// parking
NSArray *parkingArray = [NSArray arrayWithObjects:@"park 01",@"park 02",@"park 03", nil];
NSDictionary *parkingDic = [NSDictionary dictionaryWithObject:parkingArray forKey:@"parking"];
// smoking
NSArray *smokingArray = [NSArray arrayWithObjects:@"smoke 01",@"smoke 02",@"smoke 03", nil];
NSDictionary *smokingDic = [NSDictionary dictionaryWithObject:smokingArray forKey:@"smoking"];
// add all dictionary to list
[list addObject:timeDic];
[list addObject:pRoomDic];
[list addObject:parkingDic];
[list addObject:smokingDic];
// Scroll the table view to the top before it appears
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//Number of section
return [list count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//Get the dictionary object
NSDictionary *dictionary = [list objectAtIndex:section];
NSArray *array;
switch (section) {
case 0:
// time array
array = [dictionary objectForKey:@"time"];
break;
case 1:
// pRoom array
array = [dictionary objectForKey:@"pRoom"];
break;
case 2:
// parking array
array = [dictionary objectForKey:@"parking"];
break;
case 3:
// smoking array
array = [dictionary objectForKey:@"smoking"];
break;
default:
break;
}
//Number of rows
return [array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Budget";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
UITableViewCellStyleSubtitle;
}
//Get the dictionary object
NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
NSArray *array;
switch (indexPath.section) {
case 0:
// time array
array = [dictionary objectForKey:@"time"];
if (indexPath.row == row0 ) {
cell.accessoryType=UITableViewCellAccessoryCheckmark;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
break;
case 1:
// pRoom array
array = [dictionary objectForKey:@"pRoom"];
if (indexPath.row == row1) {
cell.accessoryType=UITableViewCellAccessoryCheckmark;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
break;
case 2:
// parking array
array = [dictionary objectForKey:@"parking"];
if (indexPath.row == row2) {
cell.accessoryType=UITableViewCellAccessoryCheckmark;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
break;
case 3:
// smoking array
array = [dictionary objectForKey:@"smoking"];
if (indexPath.row == row3) {
cell.accessoryType=UITableViewCellAccessoryCheckmark;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
break;
default:
break;
}
cell.textLabel.text = [array objectAtIndex:indexPath.row];
NSLog(@"index cell");
return cell;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *title = nil;
//Get the dictionary object
NSDictionary *dictionary = [sectionList objectAtIndex:0];
NSArray *array = [dictionary objectForKey:@"section"];
title = [array objectAtIndex:section];
return title;
}

#pragma mark -
#pragma mark Table view selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
switch(indexPath.section)
{
case 0:
{
UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark) {
cell1.accessoryType = UITableViewCellAccessoryNone;
row0 = 100;
timeString = @"";
}else {
NSIndexPath *SIndexPath0 = [NSIndexPath indexPathForRow:row0 inSection:0];
if ([[tableView cellForRowAtIndexPath:SIndexPath0 ] accessoryType] == UITableViewCellAccessoryCheckmark) {
[[tableView cellForRowAtIndexPath:SIndexPath0] setAccessoryType:UITableViewCellAccessoryNone];
}
if (oldIndexPath0 == nil) {
oldIndexPath0 = indexPath;
}
UITableViewCell *cell2 = nil;
if (oldIndexPath0 != indexPath) {
cell2 = [tableView cellForRowAtIndexPath:oldIndexPath0];
}
cell1.accessoryType = UITableViewCellAccessoryCheckmark;
if (cell2) {
cell2.accessoryType = UITableViewCellAccessoryNone;
}
//Get the dictionary object
NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"time"];
timeString = [array objectAtIndex:indexPath.row];
row0 = indexPath.row;
oldIndexPath0 = nil;
}
select0 = @"marked";
break;
}
case 1:
{
UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark) {
cell1.accessoryType = UITableViewCellAccessoryNone;
row1 = 100;
pRoomString = @"";
}else {
NSIndexPath *SIndexPath1 = [NSIndexPath indexPathForRow:row1 inSection:1];
if ([[tableView cellForRowAtIndexPath:SIndexPath1 ] accessoryType] == UITableViewCellAccessoryCheckmark) {
[[tableView cellForRowAtIndexPath:SIndexPath1] setAccessoryType:UITableViewCellAccessoryNone];
}
if (oldIndexPath1 == nil) {
oldIndexPath1 = indexPath;
}
UITableViewCell *cell2 = nil;
if (oldIndexPath1 != indexPath) {
cell2 = [tableView cellForRowAtIndexPath:oldIndexPath1];
}
cell1.accessoryType = UITableViewCellAccessoryCheckmark;
if (cell2) {
cell2.accessoryType = UITableViewCellAccessoryNone;
}
//Get the dictionary object
NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"pRoom"];
pRoomString = [array objectAtIndex:indexPath.row];
row1 = indexPath.row;
oldIndexPath1 = nil;
}
select1 = @"marked";
break;
}
case 2:
{
UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark) {
cell1.accessoryType = UITableViewCellAccessoryNone;
row2 = 100;
parkingString = @"";
}else {
NSIndexPath *SIndexPath2 = [NSIndexPath indexPathForRow:row2 inSection:2];
if ([[tableView cellForRowAtIndexPath:SIndexPath2 ] accessoryType] == UITableViewCellAccessoryCheckmark) {
[[tableView cellForRowAtIndexPath:SIndexPath2] setAccessoryType:UITableViewCellAccessoryNone];
}
if (oldIndexPath2 == nil) {
oldIndexPath2 = indexPath;
}
UITableViewCell *cell2 = nil;
if (oldIndexPath2 != indexPath) {
cell2 = [tableView cellForRowAtIndexPath:oldIndexPath2];
}
cell1.accessoryType = UITableViewCellAccessoryCheckmark;
if (cell2) {
cell2.accessoryType = UITableViewCellAccessoryNone;
}
//Get the dictionary object
NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"parking"];
parkingString = [array objectAtIndex:indexPath.row];
row2 = indexPath.row;
oldIndexPath2 = nil;
}
select2 = @"marked";
break;
}
case 3:
{
UITableViewCell *cell1 = [tableView cellForRowAtIndexPath:indexPath];
if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark) {
cell1.accessoryType = UITableViewCellAccessoryNone;
row3 = 100;
smokingString = @"";
}else {
NSIndexPath *SIndexPath3 = [NSIndexPath indexPathForRow:row3 inSection:3];
if ([[tableView cellForRowAtIndexPath:SIndexPath3 ] accessoryType] == UITableViewCellAccessoryCheckmark) {
[[tableView cellForRowAtIndexPath:SIndexPath3] setAccessoryType:UITableViewCellAccessoryNone];
}
if (oldIndexPath3 == nil) {
oldIndexPath3 = indexPath;
}
UITableViewCell *cell2 = nil;
if (oldIndexPath3 != indexPath) {
cell2 = [tableView cellForRowAtIndexPath:oldIndexPath3];
}
cell1.accessoryType = UITableViewCellAccessoryCheckmark;
if (cell2) {
cell2.accessoryType = UITableViewCellAccessoryNone;
}
//Get the dictionary object
NSDictionary *dictionary = [list objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"smoking"];
smokingString = [array objectAtIndex:indexPath.row];
row3 = indexPath.row;
oldIndexPath3 = nil;
}
select3 = @"marked";
break;
}
default:
break;
}
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
// Cancle button and add an event handler
self.navigationItem.leftBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:@"Cancle"
style:UIBarButtonSystemItemCancel
target:self
action:@selector(handleCancle:)];
// Cancle button and add an event handler
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:@"Use"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(handleUse:)];
}
- (void) handleCancle:(id)sender
{
// pop the controller
[self.navigationController popViewControllerAnimated:YES];
}
- (void) handleUse:(id)sender{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *fileName;
// Get row index value
fileName = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/othersString.txt"];
NSData *rowValData = [fileManager contentsAtPath:fileName];
// From NSData to NSString
NSString *rowValString = [[NSString alloc] initWithData:rowValData encoding:NSUTF8StringEncoding];
NSString *oldTimeString = @"";
NSString *oldpRoomString = @"";
NSString *oldParkingString = @"";
NSString *oldSmokingString = @"";
if (rowValString) {
// spit row string
NSArray *rowValArray = [rowValString componentsSeparatedByString:@":"];
for (int i=0; i<[rowValArray count]; i++) {
if ([rowValArray objectAtIndex:i] != @"") {
// set row value
if (i == 0 ) {
oldTimeString = [rowValArray objectAtIndex:0];
}
if (i == 1 ) {
oldpRoomString = [rowValArray objectAtIndex:1];
}
if (i == 2 ) {
oldParkingString = [rowValArray objectAtIndex:2];
}
if (i == 3) {
oldSmokingString = [rowValArray objectAtIndex:3];
}
}
}
}
if (select0 == @"") {
timeString = oldTimeString;
}
if (select1 == @"") {
pRoomString = oldpRoomString;
}
if (select2 == @"") {
parkingString = oldParkingString;
}
if (select3 == @"") {
smokingString = oldSmokingString;
}
// make othersString string
othersString = [NSString stringWithFormat:@"%@:%@:%@:%@", timeString, pRoomString, parkingString, smokingString];
// write othersString to othersString.txt file
fileName= [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/othersString.txt"];
NSData *othersData = [othersString dataUsingEncoding:NSUTF8StringEncoding];
[fileManager createFileAtPath:fileName contents:othersData attributes:nil];
// make row data in string
NSString *rowString = [NSString stringWithFormat:@"%i:%i:%i:%i", row0,row1,row2,row3];
// write othersString to othersString.txt file
fileName = [NSHomeDirectory() stringByAppendingPathComponent:@"tmp/rowString.txt"];
NSData *rowData = [rowString dataUsingEncoding:NSUTF8StringEncoding];
[fileManager createFileAtPath:fileName contents:rowData attributes:nil];
// pop the controller
[self.navigationController popViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
[list release];
}
@end

Got this stuff from this post, as this was in Japanese I changed it. Thanks to the author.

NSFetchedResultsController prepend a row or section

This is possible to do in a fairly clean way.

I'm assuming you're starting with a standard tableview set up with a standard NSFetchResultsController that uses Apple's sample code.

First you need two utility functions:

- (NSIndexPath *)mapIndexPathFromFetchResultsController:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
indexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];

return indexPath;
}

- (NSIndexPath *)mapIndexPathToFetchResultsController:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
indexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:indexPath.section];

return indexPath;
}

These should be fairly self explanatory - they're just helpers to deal with adding the extra row when we want to use an index path from the fetched results controllers to access the table, or removing it when going the other way.

Then we need to create the extra cell:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"MyCellId";

if (indexPath.section == 0 && indexPath.row == 0)
{
UITableViewCell *cell;
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.textLabel.text = NSLocalizedString(@"Extra cell text", nil);

return cell;
}

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}

[self configureCell:cell atIndexPath:indexPath];

return cell;
}

make sure we configure it correctly (configurecell will only be called for cells from the fetch results controller):

// the indexPath parameter here is the one for the table; ie. it's offset from the fetched result controller's indexes
- (void)configureCell:(SyncListViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
indexPath = [self mapIndexPathToFetchResultsController:indexPath];

id *obj = [fetchedResultsController objectAtIndexPath:indexPath];
<... perform normal cell setup ...>
}

and tell the tableview it exists:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger numberOfRows = 0;

if ([[fetchedResultsController sections] count] > 0) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
numberOfRows = [sectionInfo numberOfObjects];
}

if (section == 0)
numberOfRows++;

return numberOfRows;
}

and respond to selection:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];

if (indexPath.section == 0 && indexPath.row == 0)
{
[self doExtraAction];
return;
}

... deal with selection for other cells ...

and then remap any updates we get from the results controller:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;

indexPath = [self mapIndexPathFromFetchResultsController:indexPath];
newIndexPath = [self mapIndexPathFromFetchResultsController:newIndexPath];

switch(type) {
... handle as normal ...

How can I check if an indexPath is valid, thus avoiding an attempt to scroll to invalid index path error?

You could check

- numberOfSections
- numberOfItemsInSection:

of your UICollection​View​Data​Source to see if your indexPath is a valid one.

E.g.

extension UICollectionView {

func isValid(indexPath: IndexPath) -> Bool {
guard indexPath.section < numberOfSections,
indexPath.row < numberOfItems(inSection: indexPath.section)
else { return false }
return true
}

}


Related Topics



Leave a reply



Submit