UnwindToList with multiple NSMutableArrays - objective-c

Ok so I have 7 NSMutableArrays and they are connected to a tableview
the first table-view tells the second table-view which one to load,
and it loads fine, but each one I want to be able to add a item/cell, but
I could only get it to load for one of my views.
Here is my NSMutableArrays list of items and properties.
Properties:
#property (nonatomic) NSMutableArray *Movies;
#property (nonatomic) NSMutableArray *Tv_Shows;
#property (nonatomic) NSMutableArray *Resturuants;
#property (nonatomic) NSMutableArray *Video_Games;
#property (nonatomic) NSMutableArray *Concert_Venues;
#property (nonatomic) NSMutableArray *Foods;
#property (nonatomic) NSMutableArray *Recipes
NSMutableArray items
_Movies = [[NSMutableArray alloc]initWithObjects:#"Avatar", #"Kung Fu Panda", #"The Matrix", nil];
_Tv_Shows = [[NSMutableArray alloc]initWithObjects:#"Reguluar Show", #"Kung Fu Panda", #"Avatar The last Airbender", nil];
_Resturuants = [[NSMutableArray alloc]initWithObjects:#"Outback Steakhouse", #"Golden Corral", #"Wendy's", nil];
_Video_Games = [[NSMutableArray alloc]initWithObjects:#"black Ops", #"Call Of Duty", #"Modern Warfare", nil];
_Foods = [[NSMutableArray alloc]initWithObjects:#"Baked Bread", #"Pasta", #"Italian Meatballs", nil];
_Recipes = [[NSMutableArray alloc]initWithObjects:#"Chocolate Cookies", #"Brownies", #"Peanutbutter Fudge", nil];
_Concert_Venues = [[NSMutableArray alloc]initWithObjects:#"Pheonix", #"Buckeye", #"Maricopa", nil];
Unwind To List Method it only loads for the first item.
- (IBAction)unwindToTableViewController:(UIStoryboardSegue *)sender {
AddViewController *addViewController = (AddViewController *)sender.sourceViewController;
NSString *text = addViewController.textField.text;
//if NOT blank and NOT whitespace
if (![text length] == 0 && ![[text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
//Add it to the top of the data source.
[_Movies insertObject:text atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
//Insert it into the tableview
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
}

//Add it to the top of the data source.
[_Movies insertObject:text atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
As you can see only _movies is being loaded, you have to do the same for _TvShows,Restaurants, etc... with increasing values (as in not 0). For example
[_Restaruants insertObject:text atIndex:1];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:1];
//you may have to keep inSection:0, try it with 1 anyway

I figured it out!
- (IBAction)unwindToTableViewController:(UIStoryboardSegue *)sender {
AddViewController *addViewController = (AddViewController *)sender.sourceViewController;
NSString *text = addViewController.textField.text;
//if NOT blank and NOT whitespace
if (![text length] == 0 && ![[text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
//Add it to the top of the data source.
[_Movies insertObject:text atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
//Insert it into the tableview
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
}
Add Items under the _Movies
like so
[_Movies insertObject:text atIndex:0];
then add new ones

Related

UITableView cannot reload the data from CustomCell

I have an UITableView with CustomCells. It is a favorites list and there is star images in every CustomCell. So if I click lighted stars again they have to be disappeared and removed from properties list called fav.plist.
But when I click the lighted stars they don't disappear. I can't reload the datas in Favorite list from CustomCell.m . TO disappear the datas that I clicked the star , I have to go that View again. It is the only way to reload the data.
How can I make it reload the datas after click the star with stay at the same view?
Here is a part of my CustomCell.m code where the favorite list is (UITableView for the list is favView, the plist is fav.plist):
#property (nonatomic, retain) NSMutableArray *favList;
//First I find the item from plist which one will be removed from fav.plist.
NSString *path_fav = [[self documentsDirectory] stringByAppendingPathComponent:#"fav.plist"];
self.favList = [[NSMutableArray alloc] initWithContentsOfFile:path_fav];
for (NSInteger i=0; i<[self.favList count];i++) {
d = [self.favList objectAtIndex:i];
NSString *code=[d objectForKey:#"CODE"];
NSComparisonResult res=[code compare:self.cityLabel.text];
if(res==NSOrderedSame){
//removing from the fav.plist
[self.favList removeObjectAtIndex:i];
//Here I try to reload the data for the UITableView called favView
//In Favorite.m is my UITableView called favView
NSString *path = [[self documentsDirectory]
stringByAppendingPathComponent:#"fav.plist"];
[self.favList writeToFile:path atomically:TRUE];
Favorite *favController =[[Favorite alloc]init];
[favController.favView reloadData];
[favController.favView reloadInputViews];
}
}
Here is one part of my Favorite.m code:
- (UITableViewCell*)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"cellid";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:cellID ];
if (cell == nil)
{
cell = (CustomCell*)[[[NSBundle mainBundle]
loadNibNamed:#"CustomCell" owner:nil options:nil]
lastObject];
}
NSDictionary *d = [self.favList objectAtIndex:indexPath.row];
cell.nameLabel.text = [d objectForKey:#"NAME"];
cell.cityLabel.text = [d objectForKey:#"CODE"];
cell.index= [NSString stringWithFormat:#"%d",indexPath.row];
cell.indexPath = indexPath;
NSString *starName;
if([[d objectForKey:#"FAV"] intValue]==0){
starName=#"star.png";
}else{
starName=#"starb.png";
}
[cell.self.starbtn setImage:[UIImage imageNamed:starName] forState:UIControlStateNormal];
if((indexPath.row % 2) ==0)
cell.contentView.backgroundColor=[UIColor colorWithRed:241/256.0 green:237/256.0 blue:237/256.0 alpha:1.0];
CGSize maxSize = CGSizeMake(320/2, MAXFLOAT);
CGSize nameSize = [cell.nameLabel.text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:maxSize lineBreakMode:NSLineBreakByWordWrapping];
if(nameSize.height>=72)
nameSize.height=63;
else
nameSize.height=38;
cell.nameLabel.frame =CGRectMake(80, 0, 213, nameSize.height);
return cell;
}
Did u implement the Method
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
If yes then in this perform deletion and reload in this method.
You cannot reload a cell from itself. As far as I got your Question,you need to implement Delegate protocol for your cell. As star is pressed, call method for your button in customcell.m, which removes star from plist file and do other stuff. Then call method on delegate(your view) to reload that cell. If you don't understand I can provide u example.

Table check box just for one section objective-c

I have a uiTableView with 3 sections and different rows, I want to add check box JUST to my third sections,
I create custom cell and I linke img and label
like this picture:
![enter image description here][1]
and my code for custom cell is :
.h
: UITableViewCell
#property (strong, nonatomic) IBOutlet UIImageView *checkBox;
#property (strong, nonatomic) IBOutlet UILabel *absenceCode;
#end
.m
#synthesize checkBox;
#synthesize absenceCode;
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
// Initialization code
checkBox.image = [UIImage imageNamed:#"emptycheck-box.png"];
}
return self;
}
#end
and code for UITableViewController
viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];
NSString *staKey = #"Start";
NSString *endKey = #"End";
NSString *absKey= #"Absence";
[contents setObject:[NSArray arrayWithObjects:#"Time: 08:00 Date: Fri,3 Aug, 2012", nil] forKey:staKey];
[contents setObject:[NSArray arrayWithObjects:#"Time: 17:57 Date: Fri,3 Aug, 2012", nil] forKey:endKey];
[contents setObject:[NSArray arrayWithObjects:#"Red",#"Black",#"Blue", nil] forKey:absKey];
[keys addObject:staKey];
[keys addObject:endKey];
[keys addObject:absKey];
[self setSectionKeys:keys];
[self setSectionContents:contents];
}
cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
CheckBoxTableViewCell *cell = (CheckBoxTableViewCell*)[tableView
dequeueReusableCellWithIdentifier:#"CheckBoxTableViewCell"];
cell.imageView.image=[UIImage imageNamed:#"emptycheck-box.png"];
cell.checkBox.image = image;
cell.absenceCode.text =#"Redddd";
cell.text =contentForThisRow;
return cell;
}
would you please help me
Thanks in advance!
Something like the following should do what you want.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
if (indexPath.section != 2) {
//Set up default cell here.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
cell.textLabel.text =contentForThisRow;
return cell;
}
else {
CheckBoxTableViewCell *cell = (CheckBoxTableViewCell*)[tableView dequeueReusableCellWithIdentifier:#"CheckBoxTableViewCell"];
cell.imageView.image=[UIImage imageNamed:#"emptycheck-box.png"];
cell.checkBox.image = image;
cell.absenceCode.text =#"Redddd";
return cell;
}
}

Error -[NSIndexPath release]: message sent to deallocated instance 0x6a9d790

I create tableView with my custom cells.
here the code of the cell .h file
#interface ZUITableViewCell : UITableViewCell {
IBOutlet UITextField *_textFieldOutlet;
IBOutlet UILabel *_textLabelOutlet;
}
#property (retain, nonatomic) IBOutlet UITextField *_textFieldOutlet;
#property (retain, nonatomic) IBOutlet UILabel *_textLabelOutlet;
#end
And in my tableview controller file I create this
#import <UIKit/UIKit.h>
#import "ZUITableViewCell.h"
#protocol ZUITableViewControllerDelegate ///for main view controller
-(void) doneButtonPressed;
#end
#interface ZUITableViewController : UITableViewController {
id <ZUITableViewControllerDelegate> delegate;
NSMutableArray *menuItems;
BOOL isAddingFields;
}
#property (nonatomic, retain) NSArray *menuItems;
#property (nonatomic, assign) id<ZUITableViewControllerDelegate> delegate;
- (CGRect) GetCellHegiht: (ZUITableViewCell *) cell;
#end
I want to add new rows in my table view when user select the second row.
To make this I describe this method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
NSLog (#"row = %d", indexPath.row);
NSLog(#"INIT %p", self);
ZUITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell._textFieldOutlet becomeFirstResponder];
if (indexPath.row == 1 && isAddingFields == FALSE) {
isAddingFields = TRUE;
[menuItems insertObject:#"CC" atIndex:1];
[menuItems insertObject:#"BCC" atIndex:2];
NSIndexPath *path1 = [NSIndexPath indexPathForRow:1 inSection:0];
NSIndexPath *path2 = [NSIndexPath indexPathForRow:2 inSection:0];
NSArray *indexArray = [NSArray arrayWithObjects:path1,path2,nil];
[tableView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationTop];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[path1 release];
[path2 release];
[cell._textFieldOutlet becomeFirstResponder];
}
}
and there is my cellForRowAtIndexPath method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSLog(#"INIT %p", self);
NSLog (#"cell for row = %d", indexPath.row);
ZUITableViewCell *cell = (ZUITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelsObjects = [[NSBundle mainBundle] loadNibNamed:#"ZUITableViewCell" owner:nil options:nil];
for (id currentObject in topLevelsObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (ZUITableViewCell *) currentObject;
break;
}
}
}
if (indexPath.row == 3 && isAddingFields == FALSE){
// [cell setBounds:[self GetCellHegiht:cell]];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell._textLabelOutlet.text = [menuItems objectAtIndex:indexPath.row];
cell._textFieldOutlet.tag = indexPath.row;
[cell._textFieldOutlet setEnabled:YES];
if(indexPath.row == 0){
[cell._textFieldOutlet becomeFirstResponder];
}
return cell;
}
In debug mode as I can see after clicking to the row with indexPath.row == 1 this controller call method cellForRowAtIndexPath two times with indexPath.row = 1 and 2. But After It controller call method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
return [menuItems count];
}
again and method cellForRowAtIndexPath calling too, After program take me this error (I enable zombie) Error -[NSIndexPath release]: message sent to deallocated instance 0x6a9d790
The method [NSIndexPath indexPathForRow:inSection:] (used in path1 and path2) returns an autoreleased object, no need to call release after.

UITableView crashes when scroll down

I know there's a lot of questions about this topic but I have not be able to solve my problem...
Well, I have detected the problem, it's the contactsArray that's global. If I comment that lines, the table works fine.
The code is this:
#interface ContactsView : UIViewController <UITableViewDelegate, UITableViewDataSource>{
IBOutlet UITableView *table;
NSMutableArray * contactsArray;
}
#property (nonatomic, retain) NSMutableArray *contactsArray;
#property (nonatomic, retain) IBOutlet UITableView *table;
In viewDidLoad I do:
contactsArray = [[NSMutableArray alloc] init];
And here the implementation of each cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ContactsCell";
ContactsCell *cell = (ContactsCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ContactsCell" owner:self options:nil];
for(id currentObject in topLevelObjects){
if([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (ContactsCell *) currentObject;
break;
}
}
}
// Configure the cell...
Person *persona = [[Person alloc] init];
persona=[contactsArray objectAtIndex:indexPath.row];
[cell setCellNames:[persona name]];
[cell setCellStates:#"En Donosti"];
[persona release];
return cell;
}
If I comment the persona=[contactsArray objectAtIndex:indexPath.row]; and [cell setCellNames:[persona name]];
So, I'm pretty sure that the problem is with contactsArray
Any idea why is it crashing?
Thanks!
You must not release persona object as you just get it from array. Also the Person *persona = [[Person alloc] init]; has no effect as you immediately overwrite object you create with object from array. Fixed code should look like:
Person *persona = [contactsArray objectAtIndex:indexPath.row];
[cell setCellNames:[persona name]];
[cell setCellStates:#"En Donosti"];
return cell;

Loading data in NSUserDefaults

i have done the coding to save the highscore in NSuserdefaults, but i am not sure how can i load the data from the nsuserdefaults and display it in a table. PLease help.
NSString *name;
name = nametextbox.text;
NSDictionary *player = [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithFormat:#"%#", name], #"name",[NSString stringWithFormat:#"%d", myScore], #"score",nil];
[highScore addObject:player];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"score" ascending:NO];
[highScore sortUsingDescriptors:[NSArray arrayWithObject:sort]];
[sort release];
[[NSUserDefaults standardUserDefaults] setObject:highScore forKey:#"highScore"];
You should be able to load it just the way you'd expect (like accessing a value in an NSDictionary):
NSArray *highScore = [[NSUserDefaults standardUserDefaults] objectForKey:#"highScore"];
Update
To display the data from this array in a table view, you'll need to create a view controller and use the array as your data source. The easiest way to do this is by subclassing UITableViewController. This should get you started on the implementation of that controller:
// HighScoreViewController.h
#interface HighScoreViewController : UITableViewController {
NSArray *highScores;
}
#property (nonatomic, retain) NSArray *highScores;
#end
.
// HighScoreViewController.m
#import HighScoreViewController.h
static const NSInteger kNameLabelTag = 1337;
static const NSInteger kScoreLabelTag = 5555;
#implementation HighScoreViewController
#synthesize highScores;
- (void)viewDidLoad {
[self setHighScores:[[NSUserDefaults standardUserDefaults]
objectForKey:#"highScore"]];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.highScores count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"PlayerCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cel == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier] autorelease];
// Create UILabels for name and score and add them to your cell
UILabel *nameLabel = [[UILabel new] autorelease];
[nameLabel setTag:kNameLabelTag];
[cell.contentView addSubview:nameLabel];
UILabel *scoreLabel = [[UILabel new] autorelease];
[scoreLabel setTag:kScoreLabelTag];
[cell.contentView addSubview:scoreLabel];
// Set other attributes common to all of your cells here
// You will also need to set the frames of these labels (nameLabel.frame = CGRectMake(...))
}
NSDictionary *player = [self.highScores objectAtIndex:indexPath.row];
NSString *name = [player objectForKey:#"name"];
NSString *score = [player objectForKey:#"score"];
[(UILabel *)[cell.contentView viewWithTag:kNameLabelTag] setText:name];
[(UILabel *)[cell.contentView viewWithTag:kScoreLabelTag] setText:score];
return cell;
}
#end
A key thing to remember with UITableView is that cells get reused, so you need to be careful about where you initialize/configure your cell's subviews.