I have an UITableView that contains 3 NSArrays and 3 NSDictionaries for each array.
- (void)viewDidLoad {
[super viewDidLoad];
contentArray = [[NSMutableArray alloc] init];
self.settingsArray = [NSArray arrayWithObjects:#"Settings", nil];
NSDictionary *settingsDict = [NSDictionary dictionaryWithObject:settingsArray forKey:#"Settings"];
self.infoArray = [NSArray arrayWithObjects: #"Version 1.0", #"© Copyrights 2010", #"Developer Site", #"App Page", #"Report a Bug", nil];
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:infoArray forKey:#"Settings"];
self.contactArray = [NSArray arrayWithObjects: #"Developer Site", #"App Page", #"Report a Bug", nil];
NSDictionary *contactDict = [NSDictionary dictionaryWithObject:contactArray forKey:#"Settings"];
[contentArray addObject:infoDict];
[contentArray addObject:settingsDict];
[contentArray addObject:contactDict];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([[infoArray objectAtIndex:indexPath.row] isEqual:#"Version 1.1"]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
if ([[infoArray objectAtIndex:indexPath.row] isEqual:#"© Copyrights 2010"]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
if ([[settingsArray objectAtIndex:indexPath.row] isEqual:#"Settings"]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"NULL" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
if ([[contactArray objectAtIndex:indexPath.row] isEqual:#"Developer Site"]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
if ([[contactArray objectAtIndex:indexPath.row] isEqual:#"App Page"]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
if ([[contactArray objectAtIndex:indexPath.row] isEqual:#"Report a Bug"]) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
The problem is when I'm trying to select a row, the application is crashing
Thanks
That error will occur when you attempt to access an index beyond the bounds of an array. For example, you'll encounter an NSRangeException if your array has only one item and you ask for the object at index 3. The immediate solution is to check the array's size before querying its contents.
NSArray* exampleArray = [NSArray arrayWithObjects:#"One", #"Two", #"Three", nil];
int items = [exampleArray count];
if(indexPath.row < items) {
// do stuff
}
Related
if i have table view with custom cell. Then i want to go different view from did select of table view.. then how can i do the same my code is here.
[CCTableView registerNib:[UINib nibWithNibName:#"CCCustomCell" bundle:nil] forCellReuseIdentifier:#"CellIdentifier"];
[CCTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
arraySuper=[NSMutableArray new];
NSUserDefaults *userSave = [NSUserDefaults standardUserDefaults];
NSArray *KeysArray=[NSArray arrayWithObjects:[NSString stringWithFormat:#"Welcome - %#",[userSave valueForKey:#"userID"]], nil];
NSArray *objectArray=[NSArray arrayWithObjects:#"", nil];
[self bindValues:KeysArray withObjects:objectArray];
NSArray *KeysArray1=[NSArray arrayWithObjects:#"Case Status",#"Open Delivery Cases",#"Open Claim Cases",#"Feedback Awaiting",#"Completed Good",#"Completed bad", nil];
NSArray *objectArray1=[NSArray arrayWithObjects:#"",openDelieveryCase,openClaimCase,#"0",completeGood,#"0", nil];
[self bindValues:KeysArray1 withObjects:objectArray1];
NSArray *KeysArray2=[NSArray arrayWithObjects:#"Today's Reminder",#"Case #123456 - Update Request by the insurer. Send Insurance Proof.1",#"Case #123456 - Update Request by the insurer. Send Insurance Proof.2",#"Case #123456 - Update Request by the insurer. Send Insurance Proof.3",#"Case #123456 - Update Request by the insurer. Send Insurance Proof.4", nil];
NSArray *objectArray2=[NSArray arrayWithObjects:#"",#"",#"",#"",#"", nil];
[self bindValues:KeysArray2 withObjects:objectArray2];
}
-(void)bindValues:(NSArray*) KeysArray withObjects:(NSArray*)objectArray
{
NSMutableArray *arrayMain=[NSMutableArray new];
for (int i=0;i<[KeysArray count];i++) {
NSDictionary *dict=[NSDictionary dictionaryWithObject:[objectArray objectAtIndex:i] forKey:[KeysArray objectAtIndex:i]];
[arrayMain addObject:dict];
}
[arraySuper addObject:arrayMain];
}
//
#pragma mark - Button Menu
#pragma mark-
-(void)buttonMenu:(UIButton *)button
{
[self.menuContainerViewController toggleLeftSideMenuCompletion:nil];
}
//
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return arraySuper.count;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[arraySuper objectAtIndex:section] count];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"CellIdentifier";
//CCCustomCell *cell
cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell=[[CCCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.keyText.text=[[[[arraySuper objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] allKeys] objectAtIndex:0];
cell.objectText.text=[[[[arraySuper objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] allObjects] objectAtIndex:0];
[cell.objectText addConstraint:[NSLayoutConstraint constraintWithItem:cell.objectText
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:(cell.objectText.text.length>0)?50:0]];
if (indexPath.row==0)
{
cell.keyText.textColor=[UIColor blueColor];
cell.keyText.font=[UIFont fontWithName:#"Helvetica-Bold" size:15];
}
else
{
cell.keyText.textColor=[UIColor lightGrayColor];
cell.keyText.font=[UIFont fontWithName:#"Helvetica" size:13];
cell.objectText.textColor=[UIColor blueColor];
cell.objectText.font=[UIFont fontWithName:#"Helvetica" size:13];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
cell.keyText.text=[[[[arraySuper objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] allKeys] objectAtIndex:0];
cell.objectText.text=[[[[arraySuper objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] allObjects] objectAtIndex:0];
[cell.objectText addConstraint:[NSLayoutConstraint constraintWithItem:cell.objectText
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant: (cell.objectText.text.length>0)?50:0]];
if (indexPath.row==1)
{
NSLog(#"Csase Status Data");
DetailCaseStatus *caseStatus = [[DetailCaseStatus alloc]initWithNibName:#"DetailCaseStatus" bundle:nil];
[self.navigationController pushViewController:caseStatus animated:YES];
}
}
can u try indexPath.section == (section with which you want to comapre)
I am quite new with Objective C and I have been having trouble a a little while and I have been looking over answers, watching tutorials, and I have not been able to find a solution to my problem. Maybe its right in front of my face and I am not seeing it...I think it has something that has to do with the NSRange of my UISearch Bar. But I am not 100% sure.
I am trying to search through array that has the keys of my dictionary of countries, I have set up several NSLogs and I see that the keys are going into the array I have setup to save them in and then i get the error below...
So to my understanding of this, it is counting countryKeys which has 5, so index 4 should exist, should it not? but then it shows 0 .. 3, So I this is why I am thinking i am using NSRange incorrectly. I have watched some UISearchBar and For loop tutorials so far and i am understanding For loops and them better i guess I need to figure out NSRange then.
Let me know if you don't understand my thought process or anything that I mentioned..
Filtered Countries (
ATE,
ARE,
USA,
JAP,
CAN
)
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 4 beyond bounds [0 .. 3]'
-
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize dictTableView, mySearchBar, countriesInRegion, filteredCountries, isFiltered, regionCodes, countryKey, countryKeys, countryInfo, sortedKeysArray, regionCode, dict1;
- (void)viewDidLoad
{
[super viewDidLoad];
dict1 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"United States",#"US",#"USA", #"NAC", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"USA"];
subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"Canada", #"CA", #"CAN", #"NAC", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"CAN"];
subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"Japan", #"JP", #"JAP", #"EAS", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"JAP"];
subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"United Arab Emirates", #"AE", #"ARE", #"MEA", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"ARE"];
subDict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"Antigua and Barbuda", #"AG", #"ATE", #"LCN", nil]
forKeys: [NSArray arrayWithObjects:#"countryName", #"countryAbbrev", #"countryID", #"countryRegion", nil]];
[dict1 setObject:subDict forKey:#"ATE"];
regionCodes = [[NSMutableDictionary alloc] init];
countryKeys = [dict1 allKeys];
NSLog(#"countryKeys %#", countryKeys);
sortedKeysArray = [countryKeys sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
for (int i = 0; i < [sortedKeysArray count]; i++) {
countryKey = [sortedKeysArray objectAtIndex:i];
countryInfo = [dict1 objectForKey:countryKey]; // NSLog(#"returning countryKey to countryInfo %#", countryInfo);
regionCode = [countryInfo objectForKey:#"countryRegion"]; // NSLog(#" adding countryRegion Key to regionCode %#", regionCode);
// NSLog(#"the contents of countryInfo is %#", countryInfo);
if (![regionCodes objectForKey:regionCode]) {
countriesInRegion = [[NSMutableArray alloc] init];
[regionCodes setObject:countriesInRegion forKey:regionCode];
[countriesInRegion addObject:countryInfo]; // NSLog(#"if adding countryInfo to initialCountries %#", countryInfo);
}
else{
countriesInRegion = [regionCodes objectForKey:regionCode];
[countriesInRegion addObject:countryInfo]; // NSLog(#"else adding countryInfo to initialCountries %#", countryInfo);
}
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (isFiltered == NO)
{
return countryInfo.count;
}
else
{
return filteredCountries.count;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSArray *sortKey = [regionCodes allKeys];
sortedKeysArray = [sortKey sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
return [sortedKeysArray objectAtIndex:section];
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
NSString *regionKey = [[regionCodes allKeys] objectAtIndex:section];
countriesInRegion = [regionCodes objectForKey:regionKey];
if (isFiltered == NO)
{
return countriesInRegion.count;
}
else
{
return filteredCountries.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:#"Cell"];
UILabel *countryNameLabel = [[UILabel alloc] initWithFrame:(CGRectMake(10, 0, 220, 44))];
[countryNameLabel setBackgroundColor:[UIColor clearColor]];
UILabel *countryAbbrevLabel = [[UILabel alloc] initWithFrame:(CGRectMake(230, 0, 75, 44))];
[countryNameLabel setBackgroundColor:[UIColor clearColor]];
UILabel *countryIDLabel = [[UILabel alloc] initWithFrame:(CGRectMake(275, 0, 50, 44))];
[countryNameLabel setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:countryNameLabel];
[cell.contentView addSubview:countryAbbrevLabel];
[cell.contentView addSubview:countryIDLabel];
}
NSArray *regionKeys = [regionCodes allKeys];
NSString *regionKey = [regionKeys objectAtIndex:indexPath.section];
countriesInRegion = [regionCodes objectForKey:regionKey];
NSLog(#"Countries in Region %#", countriesInRegion);
countryInfo = [countriesInRegion objectAtIndex:indexPath.row];
NSArray *subviews = [cell.contentView subviews];
UILabel *nameLabel = [subviews objectAtIndex:0];
UILabel *abbrevLabel = [subviews objectAtIndex:1];
UILabel *idLabel = [subviews objectAtIndex:2];
// NSLog(#"6 - Countries in Region %#", countriesInRegion);
if (isFiltered == NO)
{
nameLabel.text = [countryInfo objectForKey:#"countryName"];
abbrevLabel.text = [countryInfo objectForKey:#"countryAbbrev"];
idLabel.text = [countryInfo objectForKey:#"countryID"];
// NSLog(#"5 - Our list of countries: %#", nameLabel.text);
// NSLog(#"Country Info %#",countryInfo);
}
else
{
nameLabel.text = [filteredCountries objectAtIndex:2];
abbrevLabel.text = [filteredCountries objectAtIndex:1];
idLabel.text = [filteredCountries objectAtIndex:0];
NSLog(#"4 - Here are your results: %#", filteredCountries);
}
return cell;
}
#pragma mark - UISearchBarDelegate Methods
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if (searchText.length == 0) {
isFiltered = NO;
}
else
{
isFiltered = YES;
NSLog(#"You entered %#", searchText);
filteredCountries = [[NSMutableArray alloc] init];
countryKeys = [dict1 allKeys];
NSLog(#"countryKeys %#", countryKeys);
for (int i = 0; i < countryKeys.count; i++) {
countryKey = [countryKeys objectAtIndex:i];
NSLog(#"country key is %#", countryKey);
{
NSRange countryNameRange = [countryKey rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (countryNameRange.location !=NSNotFound)
{
[filteredCountries addObject:countryKey];
NSLog(#"Filtered Countries %#", filteredCountries);
}
}
}
}
[dictTableView reloadData];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[mySearchBar resignFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
That error simply means that you are exceeding the bound of an array.
Specifically at a first sight, I think you got wrong the number of sections and that it doesn't match the number of elements in your array.
I noticed that when filtered is equal to YES you are returning filteredCountries.count for both number of rows and number of sections.
It doesn't look right and I think you should double check you indexes.
I am making a small app. And having a trouble right now. Trouble by deleting a table customized cell.
it keep removing the top cell instead of the right selected cell. I delete cell number 20, it still delete the cell number 1. I don't know why. please help me out. Really appreciate.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[sortedArray removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
and here is the array:
- (void)viewDidLoad
{
[super viewDidLoad];
if (detail == nil) {
detail = [[UrlDetail alloc] init];
}
NSString *path = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
self.arrayData = [NSMutableArray arrayWithContentsOfFile:path];
NSMutableArray *filterArr = [self filterArray];
sortedArray = [[NSMutableArray alloc] initWithArray:filterArr copyItems:YES];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(actionAddNewURL:)] autorelease];
}
and here is the filter function:
-(NSMutableArray *)filterArray
{
NSMutableArray *filterArr = [[NSMutableArray alloc] init];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[filterArr addObject:tempArray];
[tempArray release];
for (NSDictionary *item in arrayData) {
if ([tempArray count]==0)
{
[tempArray addObject:item];
}
else
{
NSDictionary *anItem = [tempArray objectAtIndex:0];
NSString *first = [[anItem objectForKey:#"url"] substringToIndex:1];
NSString *last = [[item objectForKey:#"url"] substringToIndex:1];
if ( [first isEqualToString:last])
{
[tempArray addObject:item];
} else
{
tempArray = [[NSMutableArray alloc] init];
[tempArray addObject:item];
[filterArr addObject:tempArray];
[tempArray release];
}
}
}
// NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:filterArr copyItems:YES];
return filterArr;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if([sortedArray count]>0){
NSLog(#"number of section: %d", [sortedArray count]);
return [sortedArray count];
}
return 0;
}
- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section
{
if (isTab) {
if ([self.sortedArray count] > section) {
NSDictionary *dictionary = [[sortedArray objectAtIndex:section] objectAtIndex:0];
NSString *string = [dictionary objectForKey:#"url"];
return [NSString stringWithFormat:#"%#", [[string substringToIndex:1] uppercaseString]];
}
else return nil;
} else
{
return nil;
}
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = myOwnCell;
}
NSDictionary *dataItem = [[sortedArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.urlName.text = [dataItem objectForKey:#"url"];
cell.titleLabel.text = [dataItem objectForKey:#"title"];
cell.urlName.font = [UIFont italicSystemFontOfSize:14.0];
cell.imageIcon.image = [UIImage imageNamed:[dataItem objectForKey:#"image"]];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Configure the cell.
return cell;
}
Try this one if it works:
- (void) tableView:(UITableView *)aTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSString *key = [[sortedArray allKeys] objectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[sortedArray removeObjectForKey:key];
}
}
I am getting a crash at line [selectedSession release]; in dealloc:
Default [NSCheapMutableString release]: message sent to deallocated instance
I don't understand why isn't this normal to put in dealloc?
All current code below:
LogViewController
#implementation LogViewController
#synthesize fetchedResultsController = __fetchedResultsController;
#synthesize managedObjectContext;
#synthesize logArray;
#synthesize logTableView;
#synthesize imageView;
#synthesize session;
#synthesize selectedSession;
- (void)dealloc
{
[logArray release];
[logTableView release];
[session release];
[__fetchedResultsController release];
[managedObjectContext release];
[imageView release];
[selectedSession release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
self.logTableView.rowHeight = 47;
[super viewDidLoad];
self.navigationItem.title = #"Log";
logTableView.backgroundColor = [UIColor clearColor];
logTableView.separatorColor = [UIColor grayColor];
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:24/255.0 green:83/255.0 blue:170/255.0 alpha:1.0];
self.logArray = [[NSArray alloc]initWithObjects:#"Today", #"Previous", #"Past Week", #"Past Month", #"All Workouts", nil];
if (managedObjectContext == nil)
{
self.managedObjectContext = [(CurlAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
}
- (void)viewDidUnload
{
self.logTableView = nil;
self.fetchedResultsController = nil;
self.imageView = nil;
self.managedObjectContext = nil;
[super viewDidUnload];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.logArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
TDBadgedCell *cell = [[[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(TDBadgedCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
cell.textLabel.textColor = [UIColor blackColor];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = [logArray objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor clearColor];
cell.imageView.image = [UIImage imageNamed:#"17-bar-chart.png"];
UIImageView *myImageView = nil;
myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"silvercell5.png"]];
[cell setBackgroundView:myImageView];
[myImageView release];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM d, y"];
NSDate *date = nil;
if (indexPath.row == 0)
{
date = [NSDate date];
NSString *dateString = [dateFormatter stringFromDate:date];
cell.badgeString = dateString;
}
else if (indexPath.row == 1)
{
if ([[self.fetchedResultsController fetchedObjects]count] > 1)
{
self.session = [[self.fetchedResultsController fetchedObjects]objectAtIndex:1];
NSDate *date = self.session.timeStamp;
NSString *dateString = [dateFormatter stringFromDate:date];
cell.badgeString = dateString;
}
else
{
cell.badgeString = #"None";
}
}
else if (indexPath.row > 1)
{
cell.badgeString = [NSString stringWithFormat:#"%i", [[self.fetchedResultsController fetchedObjects]count]];
}
cell.badgeColor = [UIColor colorWithRed:24/255.0 green:83/255.0 blue:170/255.0 alpha:1.0];
[dateFormatter release];
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.row == 0 || indexPath.row == 1)
{
SessionViewController *detailViewController = [[SessionViewController alloc] initWithNibName:#"SessionViewController" bundle:nil];
detailViewController.title = [logArray objectAtIndex: indexPath.row];
self.selectedSession = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];
detailViewController.selectedSession = self.selectedSession;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM d, y"];
NSString *dateString = [dateFormatter stringFromDate:selectedSession.timeStamp];
detailViewController.title = dateString;
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
[dateFormatter release];
}
else
{
LogResultsViewController *detailViewController = [[LogResultsViewController alloc] initWithNibName:#"LogResultsTableViewController" bundle:nil];
detailViewController.title = [logArray objectAtIndex: indexPath.row];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController != nil)
{
return fetchedResultsController;
}
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Session" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0] ;
NSDate *today = [NSDate date];
NSDate *thisWeek = [today dateByAddingTimeInterval: -604800.0];
NSDate *thisMonth = [today dateByAddingTimeInterval: -2629743.83]; // Use NSCalendar for
if (indexPath.row ==2)
{
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"(date >= %#) AND (date <= %#)", thisWeek, today]];
}
else if (indexPath.row ==3)
{
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"(date >= %#) AND (date <= %#)", thisMonth, today]];
}
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
NSLog(#"Number of Objects = %i",
[[fetchedResultsController fetchedObjects] count]);
return fetchedResultsController;
NSLog(#"Number of Objects = %i",
[[fetchedResultsController fetchedObjects] count]);
}
#pragma mark - Fetched results controller delegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.logTableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.logTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.logTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.logTableView;
switch(type)
{
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.logTableView endUpdates];
}
LogResultsViewController
#implementation LogResultsViewController
#synthesize fetchedResultsController = __fetchedResultsController;
#synthesize managedObjectContext;
#synthesize resultsTableView;
#synthesize selectedSession;
- (void)dealloc
{
[__fetchedResultsController release];
[managedObjectContext release];
[selectedSession release];
[resultsTableView release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.resultsTableView.separatorColor = [UIColor grayColor];
self.resultsTableView.rowHeight = 50;
[self managedObjectContext];
}
- (NSManagedObjectContext *)managedObjectContext
{
if (managedObjectContext != nil)
{
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [(CurlAppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator];
if (coordinator != nil)
{
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return managedObjectContext;
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.managedObjectContext = nil;
self.fetchedResultsController = nil;
self.resultsTableView = nil;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
Session *session = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"eeee, MMM d, y"];
NSString *dateString = [dateFormatter stringFromDate:session.timeStamp];
NSDate *lastDate = session.timeStamp;
NSDate *todaysDate = [NSDate date];
NSTimeInterval lastDiff = [lastDate timeIntervalSinceNow];
NSTimeInterval todaysDiff = [todaysDate timeIntervalSinceNow];
NSTimeInterval dateDiff = todaysDiff-lastDiff;
NSTimeInterval dayDifference = dateDiff/86400;
int days = (int) dayDifference;
NSLog(#"%i days",days);
cell.textLabel.text = dateString;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.detailTextLabel.text = [NSString stringWithFormat: #"%i days ago", days];
cell.detailTextLabel.textColor = [UIColor colorWithRed:24/255.0 green:83/255.0 blue:170/255.0 alpha:1.0];
cell.imageView.image = [UIImage imageNamed:#"11-clock.png"];
self.resultsTableView.tableFooterView = [[[UIView alloc] init] autorelease];
UIImageView *myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"silvercell3.png"]];
[cell setBackgroundView:myImageView];
[dateFormatter release];
[myImageView release];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the managed object for the given index path
NSManagedObjectContext *context = [__fetchedResultsController managedObjectContext];
[context deleteObject:[__fetchedResultsController objectAtIndexPath:indexPath]];
// Commit the change.
NSError *error = nil;
// Update the array and table view.
if (![managedObjectContext save:&error])
{
// Handle the error.
}
//[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SessionViewController *sessionViewController = [[SessionViewController alloc] initWithNibName:#"SessionViewController" bundle:nil];
selectedSession = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];
sessionViewController.selectedSession = self.selectedSession;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM d, y"];
NSString *dateString = [dateFormatter stringFromDate:selectedSession.timeStamp];
sessionViewController.title = dateString;
[self.navigationController pushViewController:sessionViewController animated:YES];
[sessionViewController release];
[dateFormatter release];
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController != nil)
{
return fetchedResultsController;
}
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Session" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
NSError *error = nil;
if (![fetchedResultsController performFetch:&error])
{
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return fetchedResultsController;
}
#pragma mark - Fetched results controller delegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.resultsTableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.resultsTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.resultsTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.resultsTableView;
switch(type)
{
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.resultsTableView endUpdates];
}
SessionViewController
#implementation SessionViewController
#synthesize exerciseArray;
#synthesize selectedSession;
- (void)dealloc
{
[exerciseArray release];
[selectedSession release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(IBAction)showActionSheet {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Share" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Twitter",#"Facebook",nil];
[actionSheet showInView:self.tabBarController.view];
[actionSheet release];
}
- (void)tweet
{
SHKItem *aTweet = [SHKItem text:[NSString stringWithFormat: #"Twitter: testing 1,2,3."]];
[SHKTwitter shareItem:aTweet];
}
- (void)facebook
{
SHKItem *post = [SHKItem text: [NSString stringWithFormat: #"Facebook: testing 1,2,3."]];
// post.URL = [NSURL URLWithString:#"http://sugarrush-app.com/"];
[SHKFacebook shareItem:post];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *actionButton = [[UIBarButtonItem alloc] initWithTitle:#"Share" style:UIBarButtonItemStylePlain target:self action:#selector(showActionSheet)];
self.navigationItem.rightBarButtonItem = actionButton;
[actionButton release];
NSSet *exercises = [self.selectedSession valueForKey:#"exercises"];
NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"timeStamp" ascending:YES]];
NSArray *sorted = [exercises sortedArrayUsingDescriptors:sortDescriptors];
self.exerciseArray = sorted;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [exerciseArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
Exercise *exercise = (Exercise *)[exerciseArray objectAtIndex:indexPath.row];
cell.textLabel.text = exercise.name;
return cell;
}
#end
The only objects you should be releasing or setting to nil in viewDidUnload are like buttons, labels, textBoxes etc.
When you do self.selectedSession = nil, for example, it is calling the release for that method; that is the point of properties, they handle the allocs and releases.
You posted a tableView:didSelectRowAtIndexPath:, but I don't think you told us which class that was in.
In any case, that method seems to have a bug:
selectedSession = (Session *)[__fetchedResultsController objectAtIndexPath:indexPath];
sessionViewController.selectedSession = self.selectedSession;
I think on the first line, you meant to say self.selectedSession, assuming you go on to release selectedSession in this class' dealloc. (This may not be your only issue)
EDIT:
You should set properties to nil in viewDidUnload if and only if those properties were set as a result of the loading of the view from your nib, or were set in loadView, or in viewDidLoad. The reason you're doing this is because viewDidLoad or loadView may be called more than once during the lifetime of the view controller.
EDIT:
Check that you are using the property when setting fetchedResultsController and make sure you aren't setting that to nil on viewDidUnload.
Dont set selectedSession and exerciseArray to nil in viewDidUnload.
Since you're doing that, it will crash in the dealloc as you're trying to release nil objects.
Also, before you release arrays, it's always a good idea to call [array removeAllObjects].
in your viewDidLoad method you are setting self.selectedSession and self.exerciseArray to nil. You should only set interface outlets to nil in viewDidLoad. But this isn't the cause of your crash because by the time you get to dealloc, you are just sending release to nil.
you might want to look into the contents of the selectedSession Object. you might be over releasing an NSString in one of it's members
I have an UIViewController with a table in it. Tapping a blue disclosure icon makes the view controller present a UINavigationController. This works fine and does make the navigation controller show up, but without a navigation bar, as below:
How would I go about making that magical Navbar showing up again? I really need it to present a map in the nav controller, and right now, that does not work.
EDIT: Here's the code I use to show it:
// scanned recently table view thing
- (void)tableView:(UITableView *)tableVieww didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableVieww deselectRowAtIndexPath:indexPath animated:YES];
if(indexPath.section == 0) {
NSString *info = [[scannedBackups objectAtIndex:indexPath.row] objectForKey:#"data"];
NSArray *items = [info componentsSeparatedByString:#"&"];
scanCodeViewCohntroller.dict = [[NSMutableDictionary alloc] init];
int o;
for (o = 0; o < [items count]; o++) {
NSArray *secondItems = [[items objectAtIndex:o] componentsSeparatedByString:#"="];
[scanCodeViewCohntroller.dict setObject:[secondItems objectAtIndex:1] forKey:[secondItems objectAtIndex:0]];
}
/*NSError *err;
scanCodeViewCohntroller.dict = [NSPropertyListSerialization propertyListWithData:[foo dataUsingEncoding:NSUnicodeStringEncoding] options:NSPropertyListMutableContainersAndLeaves format:kCFPropertyListXMLFormat_v1_0 error:&err];
if(err != nil) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Corrupted Data" message:[NSString stringWithFormat:#"Your Scanned Backup Data Store is corrupted. It will now be erased. %#", [err localizedDescription]] delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
scannedBackups = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:#"%#/scannedCodes.plist", documentsDirectory];
[scannedBackups writeToFile:fullFileName atomically:NO];
[tableView reloadData];
}*/
[scanCodeViewCohntroller.dict setObject:[[scannedBackups objectAtIndex:indexPath.row] objectForKey:#"date"] forKey:#"date"];
[scanCodeViewCohntroller initalizeData];
[self presentModalViewController:scanCodeViewCohntroller animated:YES];
}
}
You need to get the navigation controller and invoke setNavigationBarHidden:animated:. So, try:
[detailController.navigationController setNavigationBarHidden:NO animated:NO];
Edit:
Based on your edit, I would suggest replacing the final line:
[self presentModalViewController:scanCodeViewCohntroller animated:YES];
with:
[self.navigationController pushViewController:scanCodeViewCohntroller animated:YES];