This is my custom table view cell, I want to change those values in every 1 minute (values will load from server). I have already set an Nstimer and tried to reload the tableview. Data in my array is changing fine, but value in the uitableviewcell is not changing.
Code:
Tableviewcontroller.m
-(void) loadView
{
parsejson = [ParseJson alloc];
defaults=[NSUserDefaults standardUserDefaults];
items=[NSArray arrayWithObjects:#" data1",#" data2 ", nil];
usercount=[NSArray arrayWithObjects:
[parsejson getdata:[defaults valueForKey:#"userid"]],#" 0 ", nil];
listtimer = [NSTimer scheduledTimerWithTimeInterval:60.0 // start timer ( interval 2 secs )
target:self
selector:#selector(reloadlist:)
userInfo:nil
repeats:YES];
}
- (void)reloadlist:(NSTimer*)timer
{
NSLog(#"list reload " );
items=[NSArray arrayWithObjects:#" data1",#" data2 ", nil];
usercount=[NSArray arrayWithObjects:
[parsejson getdata:[defaults valueForKey:#"userid"]],#" 0 ", nil];
//UITableView *tv = (UITableView *)self.view;
[self.tableview reloadData];
// NSIndexPath *a = [NSIndexPath indexPathForRow:0 inSection:0]; // I wanted to update this cell specifically
// NearestListCell *c = (NearestListCell *)[tv cellForRowAtIndexPath:a];
//c.count=[usercount objectAtIndex:0];
//[tv beginUpdates];
//// [tv reloadRowsAtIndexPaths:usercount withRowAnimation:UITableViewRowAnimationRight];
//[tv endUpdates];
// [tv reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [usercount count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NearmeListIdentifier";
listCell *cell = (listCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"listCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.text.text = [items objectAtIndex:indexPath.row];
cell.data11.text = [usercount objectAtIndex:indexPath.row];
cell.data22.text = #" 0.0 ";
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// 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];
*/
}
#end
Viewcontroller.h
#interface Viewcontroller : UIViewController
{
Tableviewcontroller *Tablecontroller;
IBOutlet UITableView *myTable;
}
#end
Viewcontroller.m
-(void)viewDidLoad
{
[super viewDidLoad];
defaults = [NSUserDefaults standardUserDefaults];
if (Tablecontroller == nil)
{
Tablecontroller = [[Tableviewcontroller alloc] init];
}
[myTable setDataSource:Tablecontroller];
[myTable setDelegate:Tablecontroller];
Tablecontroller.view = Tablecontroller.tableView;
}
Please try this code : its working fine here
/* FirstTVContoller.h */
#import <Foundation/Foundation.h>
#interface FirstTVContoller : UITableViewController <UITableViewDataSource, UITableViewDelegate>{
NSMutableArray *items;
}
#end
/* FirstTVContoller.m */
#import "FirstTVContoller.h"
#import "SecondTVController.h"
#implementation FirstTVContoller
-(void) loadView
{
if (items == nil) {
items = [[NSMutableArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5",#"6",#"6",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16",#"17",nil] retain];
}
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return [items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:#"MyIdentifier"];
}
cell.textLabel.text = [NSString stringWithFormat:#"1.%#" ,[items objectAtIndex:indexPath.row]];
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
//Delete the object from the table.
[items removeObjectAtIndex:indexPath.row];
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
-(void) dealloc
{
[items release];
[super dealloc];
}
#end
/* SecondTVController.h */
#import <Foundation/Foundation.h>
#interface SecondTVController : UITableViewController <UITableViewDataSource, UITableViewDelegate>{
int numberOfCells;
}
#end
/* SecondTVController.m */
#import "SecondTVController.h"
#implementation SecondTVController
-(void) viewDidLoad
{
numberOfCells = 20;
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return numberOfCells;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellSelectionStyleNone reuseIdentifier:#"MyIdentifier"];
}
cell.textLabel.text = [NSString stringWithFormat:#"2.%d", indexPath.row];
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
//Delete the object from the table.
numberOfCells -=1;
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
}
}
#end
/* TwoTableViewsViewController.h */
#import <UIKit/UIKit.h>
#import "FirstTVContoller.h"
#import "SecondTVController.h"
#interface TwoTableViewsViewController : UIViewController{
FirstTVContoller *firstController;
SecondTVController *secondController;
IBOutlet UITableView *firstTable;
IBOutlet UITableView *secondTable;
}
#end
/* TwoTableViewsViewController.m */
#import "TwoTableViewsViewController.h"
#implementation TwoTableViewsViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
if (firstController == nil) {
firstController = [[FirstTVContoller alloc] init];
}
if (secondController == nil) {
secondController = [[SecondTVController alloc] init];
}
[firstTable setDataSource:firstController];
[secondTable setDataSource:secondController];
[firstTable setDelegate:firstController];
[secondTable setDelegate:secondController];
firstController.view = firstController.tableView;
secondController.view = secondController.tableView;
}
- (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)dealloc {
[firstController release];
[secondController release];
[firstTable release];
[secondTable release];
[super dealloc];
}
Let me know if you still face any problems. This will work for sure for n-no. of UITableViews.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UITableViewController
#end
ViewController.m
#import "ViewController1.h"
#implementation ViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [usercount count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NearmeListIdentifier";
listCell *cell = (listCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"listCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.text.text = [items objectAtIndex:indexPath.row];
cell.data11.text = [usercount objectAtIndex:indexPath.row];
cell.data22.text = #" 0.0 ";
return cell;
}
- (void)reloadlist:(NSTimer*)timer
{
NSLog(#"list reload " );
items=[NSArray arrayWithObjects:#" data1",#" data2 ", nil];
usercount=[NSArray arrayWithObjects:
[parsejson getdata:[defaults valueForKey:#"userid"]],#" 0 ", nil];
[self.tableView reloadData];
}
-(void) loadView
{
parsejson = [ParseJson alloc];
defaults=[NSUserDefaults standardUserDefaults];
items=[NSArray arrayWithObjects:#" data1",#" data2 ", nil];
usercount=[NSArray arrayWithObjects:
[parsejson getdata:[defaults valueForKey:#"userid"]],#" 0 ", nil];
listtimer = [NSTimer scheduledTimerWithTimeInterval:60.0 // start timer ( interval 2 secs )
target:self
selector:#selector(reloadlist:)
userInfo:nil
repeats:YES];
}
Please try this code and let me know if you face any problems.Thanks
Why don't you try
[self.tableView reloadData];
instead of
UITableView *tv = (UITableView *)self.view;
[tv reloadData];
Only if your super class is UITableViewController.If not then make an outlet for tableView and reload table through it.
have you used this 'setNeedsDisplay' as
[cell.data11 setNeedsDisplay] if cellForRow is calling.
Please change below code :
/* TwoTableViewsViewController.m */
- (void)viewDidLoad {
[super viewDidLoad];
if (firstController == nil) {
firstController = [[FirstTVContoller alloc] init];
}
if (secondController == nil) {
secondController = [[SecondTVController alloc] init];
}
[firstTable setDataSource:firstController];
[secondTable setDataSource:secondController];
[firstTable setDelegate:firstController];
[secondTable setDelegate:secondController];
firstController.view = firstController.tableView;
secondController.view = secondController.tableView;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(reloadData:) name:#"ReloadFirstTable" object:nil];
}
-(void)reloadData:(id)sender
{
[firstTable reloadData];
}
/* FirstTVContoller.m */
- (void)reloadlist:(NSTimer*)timer
{
NSLog(#"list reload " );
self.items = [NSMutableArray arrayWithObjects:#"data1",#" data2 ", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"ReloadFirstTable" object:nil];
}
Please use NSNotificationCenter to reload Data.
I fixed the issue. Forgot to reload UITableview object in viewcontroller. I removed the NStimer from Tableviewcontroller.m and placed it in the Viewcontroller.m.
The changed code:
TableViewController.m
-(void) loadView
{
parsejson = [ParseJson alloc];
defaults=[NSUserDefaults standardUserDefaults];
items=[NSArray arrayWithObjects:#" data1",#" data2 ", nil];
usercount=[NSArray arrayWithObjects:
[parsejson getdata:[defaults valueForKey:#"userid"]],#" 0 ", nil];
**// removed the nstimer from here.**
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [usercount count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Added these 2 lines of code here.
items=[NSArray arrayWithObjects:#" data1",#" data2 ", nil];
usercount=[NSArray arrayWithObjects:[parsejson getNearestUsercount:[defaults valueForKey:#"userid"]],#" 0 ", nil];
static NSString *CellIdentifier = #"NearmeListIdentifier";
listCell *cell = (listCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"listCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.text.text = [items objectAtIndex:indexPath.row];
cell.data11.text = [usercount objectAtIndex:indexPath.row];
cell.data22.text = #" 0.0 ";
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// 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];
*/
}
#end
Viewcontroller.m
-(void)viewDidLoad
{
[super viewDidLoad];
defaults = [NSUserDefaults standardUserDefaults];
if (Tablecontroller == nil)
{
Tablecontroller = [[Tableviewcontroller alloc] init];
}
[myTable setDataSource:Tablecontroller];
[myTable setDelegate:Tablecontroller];
Tablecontroller.view = Tablecontroller.tableView;
// I Put the Nstimer here.
aTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 // start timer ( interval 2 secs )
target:self
selector:#selector(timerTicked:)
userInfo:nil
repeats:YES];
}
- (void)timerTicked:(NSTimer*)timer
{
[myTable.self reloadData];
}
Thank You all for helping me.
Related
RootViewController.h
#import <UIKit/UIKit.h>
#interface RootViewController : UITableViewController {
NSMutableArray *petsArray;
}
#property (nonatomic, strong) NSMutableArray *petsArray;
#end
RootViewController.m
#import "RootViewController.h"
#import "PetsViewController.h"
#interface RootViewController ()
#end
#implementation RootViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
petsArray = [[NSMutableArray alloc] init];
[petsArray addObject:#"Dog"];
[petsArray addObject:#"Cat"];
[petsArray addObject:#"Snake"];
[self setTitle:#"PETS !"];
// 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;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [petsArray 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];
}
// Configure the cell...
cell.textLabel.text = [petsArray objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - Table view delegate
I think that the problem is in didSelectRowAtIndexPath which I can't use in storyboarded project.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
PetsViewController *pets = [[PetsViewController alloc] initWithNibName:#"PetsViewController" bundle:nil];
if ([[petsArray objectAtIndex:indexPath.row] isEqual:#"Dog"]) {
pets.petsInt = 0;
[pets setTitle:[petsArray objectAtIndex:indexPath.row]];
}
if ([[petsArray objectAtIndex:indexPath.row] isEqual:#"Cat"]) {
pets.petsInt = 1;
[pets setTitle:[petsArray objectAtIndex:indexPath.row]];
}
if ([[petsArray objectAtIndex:indexPath.row] isEqual:#"Snake"]) {
pets.petsInt = 2;
[pets setTitle:[petsArray objectAtIndex:indexPath.row]];
}
[self.navigationController pushViewController:pets animated:YES];
}
#end
PetsViewController.h
#import <UIKit/UIKit.h>
#interface PetsViewController : UITableViewController {
NSMutableArray *dogArray;
NSMutableArray *catArray;
NSMutableArray *snakeArray;
int petsInt;
}
#property int petsInt;
#end
PetsViewController.m
#import "PetsViewController.h"
#interface PetsViewController ()
#end
#implementation PetsViewController
#synthesize petsInt;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
dogArray = [[NSMutableArray alloc] initWithObjects:#"HAF",#"hafo", #"hafinio", nil];
catArray = [[NSMutableArray alloc] initWithObjects:#"MYAU",#"myainio", #"mya lya lya", nil];
snakeArray = [[NSMutableArray alloc] initWithObjects:#"fshhhhh",#"fsssss", #"xrt", nil];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (petsInt == 0) return [dogArray count];
if (petsInt == 1) return [catArray count];
if (petsInt == 2) return [snakeArray count];
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"PetsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
if (petsInt == 0) cell.textLabel.text = [dogArray objectAtIndex:indexPath.row];
if (petsInt == 1) cell.textLabel.text = [catArray objectAtIndex:indexPath.row];
if (petsInt == 2) cell.textLabel.text = [snakeArray objectAtIndex:indexPath.row];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
#pragma mark - Table view delegate
- (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];
*/
}
#end
[self performSegueWithIdentifier:#"SEGUE_NAME" sender:self];
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"SEGUE_NAME"]) {
PetsViewController *pets = [segue destinationViewController];
[pets setPetsInt:0];
[pets setTitle:#"Title"];
}
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSIndexPath *indexPath = self.tableView.indexPathForSelectedRow;
if ([[gazel objectAtIndex:indexPath.row] isEqual:#"<էրեբունի> Օդանավակայան"]) {
KangarList *kang = [segue destinationViewController];
kang.kangarInt = 0;
[kang setTitle:[gazel objectAtIndex:indexPath.row]];
}
if ([[gazel objectAtIndex:indexPath.row] isEqual:#"<էրեբունի> Օդանավակայան"]) {
KangarList *kang = [segue destinationViewController];
kang.kangarInt = 1;
[kang setTitle:[gazel objectAtIndex:indexPath.row]];
}
if ([[gazel objectAtIndex:indexPath.row] isEqual:#"<էրեբունի> Օդանավակայան"]) {
KangarList *kang = [segue destinationViewController];
kang.kangarInt = 2;
[kang setTitle:[gazel objectAtIndex:indexPath.row]];
}
if ([[gazel objectAtIndex:indexPath.row] isEqual:#"<էրեբունի> Օդանավակայան"]) {
KangarList *kang = [segue destinationViewController];
kang.kangarInt = 3;
[kang setTitle:[gazel objectAtIndex:indexPath.row]];
}
}
i have tried many ways and i finaly realized the right method, but it works only when under view did load method objects have only one description but if it hase something like thise
gazel = [[NSMutableArray alloc] init];
Data *data = [[Data alloc] init];
data.title = #"<էրեբունի> Օդանավակայան";
data.subtitle = #"Հարաֆ Արևմտյան Թաղամաս";
data.photo = 1;
[gazel addObject:data];
its not working
I'm trying to be able to insert an object into my table, but it crashes because of an uncaught exception whenever I hit the add button. It says
Attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update
Here's my main view controller which handles all my table stuff...
#import "MasterViewController.h"
#import "DetailViewController.h"
#define kFileName #"steakNames.plist"
#interface MasterViewController () {
NSMutableArray *_objects;
}
#end
#implementation MasterViewController
#synthesize steakName;
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFileName];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Master", #"Master");
}
return self;
}
- (void)viewDidLoad
{
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
_objects = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
}
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)insertNewObject:(id)sender
{
if (!steakName) {
steakName = #"No name";
}
[_objects insertObject:[self steakName] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _objects.count;
}
// Customize the appearance of table view cells.
- (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];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSDate *object = [_objects objectAtIndex:indexPath.row];
cell.textLabel.text = [object description];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.detailViewController) {
self.detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
}
NSDate *object = [_objects objectAtIndex:indexPath.row];
self.detailViewController.detailItem = object;
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
- (void)applicationWillResignActive:(NSNotification *)notification {
[_objects writeToFile:[self dataFilePath] atomically:YES];
}
#end
Most likely the cause of the error is that this returns 0:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return ...;
}
I would suggest that you first take a complete working example of table view with all its required methods and start from there.
Generally you need to implement these methods:
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
So far there is no issue with any NSMutableArray, anyway you cannot insert an object at an index if the array does not yet have the number of objects, eg insert at index 4 but the array has only 2 objects. You can always add objects to NSMutableArray and increase the number of objects in this array.
I have two views, the first (view A) is a table view. Every row has a disclosure button, when I click on the button I display the second view (view B) which is a table view too. When i click on a row, I want to pass the data to view A and display it as detailTextLabel.
#import <UIKit/UIKit.h>
#interface A : UIViewController <UITableViewDelegate, UITableViewDataSource> {
NSDictionary *listData;
NSArray *keys;
}
#property (nonatomic, retain) NSDictionary *listData;
#property (nonatomic, retain) NSArray *keys;
#end
#import "A.h"
#implementation A
#synthesize listData;
#synthesize keys;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[listData release];
[keys release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"Criteres" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
self.listData = dict;
[dict release];
NSArray *array = [[listData allKeys]sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
self.keys = array;
[super viewDidLoad];
}
- (void)viewDidUnload
{
self.listData = nil;
self.keys = nil;
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark Table View Data Source Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [keys count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [listData objectForKey:key];
return [nameSection count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *key = [keys objectAtIndex:section];
return key;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [listData objectForKey:key];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:SectionsTableIdentifier] autorelease];
}
cell.textLabel.text = [nameSection objectAtIndex:row];
if (section == 0) {
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
if (row == 2)
cell.detailTextLabel.text = #"En m2";
if (row == 1)
cell.detailTextLabel.text = #"En €";
}
if (section == 1) {
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
}
return cell;
}
#pragma mark -
#pragma mark Table Delegate Methods
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = 2;
return row;
}
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
return indexPath;
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *ownerCell = [tableView cellForRowAtIndexPath:indexPath];
if ([ownerCell.textLabel.text isEqualToString:#"Ecole"]) {
B *prixview = [[B alloc]init];
[self.navigationController pushViewController:prixview animated:YES];
prixview.title = #"prix";
}
if ([ownerCell.textLabel.text isEqualToString:#"Crèche"]) {
B *prixview = [[B alloc]init];
[self.navigationController pushViewController:prixview animated:YES];
prixview.title = #"Prix";
}
}
#end
#import <UIKit/UIKit.h>
#interface B : UIViewController <UITableViewDelegate, UITableViewDataSource> {
NSArray *typetab;
NSInteger radioSelectionTypeBien;
NSString *radioSelectionTypeBienString;
}
#property (nonatomic, retain) NSArray *typetab;
#property (nonatomic, retain) NSString *radioSelectionTypeBienString;
#end
#import "B.h"
#implementation B
#synthesize typetab;
#synthesize radioSelectionTypeBienString;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[self.radioSelectionTypeBienString release];
[self.typetab release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:#"Critères"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(backButtonActionTypeBien:)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
radioSelectionTypeBien = -1;
NSArray *type = [[NSArray alloc]initWithObjects:#"Appartement",#"Maison",#"Commerce", nil ];
self.typetab = type;
[type release];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(IBAction)backButtonActionTypeBien: (id)sender
{
[self.navigationController pushViewController:self.navigationController.parentViewController animated:YES];
}
- (void)viewDidUnload
{
self.radioSelectionTypeBienString = nil;
self.typetab = nil;
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.typetab count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) { cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.text = [typetab objectAtIndex:indexPath.row];
if (indexPath.row == radioSelectionTypeBien){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
radioSelectionTypeBien = indexPath.row;
radioSelectionTypeBienString = [tableView cellForRowAtIndexPath:indexPath].textLabel.text;
[tableView reloadData];
}
#end
Usually i write a method in the controller B like:
-(voi)initVCwithString:(NSString*)_string andSomeObject:(NSObject *)_obj;
(so the controller B must have 2 ivar, a string and an object, that you have to set in this method)
then call this in your didSelectRowAtIndexPath: from the controller A
...
B _vcB=//alloc..init..etc
[_vcB initVCwithString:yourCell.textLabel.text andSomeObject:someObj];
[self.navigationController pushViewController:_vcB animated:YES];
[_vcB release];
Then in cellForRowAtIndexPath of B set cell.detailTextLabel.text=yourStringIvar;
Hope this helps.
Basically there are two possibilities that seems to be suitable. You can write a custom delegate method which pass the value to the A controller, or you can make a notification via notification centre, which can then assign the value to the A controller by catching the notification which will be triggered by picking a cell in the controller B.
I am trying to make my UITableView Editable but I'm having some trouble with the code, specifically with the commitEditingStyle method. It is not working I think the method I have is only for plist and not for an array by itself.
#import "RoutineTableViewController.h"
#import "AlertPrompt.h"
#implementation RoutineTableViewController
#synthesize myArray;
- (void)dealloc
{
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
myArray = [[NSMutableArray alloc] init];
myData = [[NSMutableArray arrayWithContentsOfFile:#"mydata"] retain];
if (myData == nil)
{
myData = [NSMutableArray array];
}
[super viewDidLoad];
UIBarButtonItem * addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(showPrompt)];
[self.navigationItem setLeftBarButtonItem:addButton];
[addButton release];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
-(void)showPrompt
{
AlertPrompt *prompt = [AlertPrompt alloc];
prompt = [prompt initWithTitle:#"Add Workout Day" message:#"\n \n Please enter title for workout day" delegate:self cancelButtonTitle:#"Cancel" okButtonTitle:#"Add"];
[prompt show];
[prompt release];
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex])
{
NSString *entered = [(AlertPrompt *)alertView enteredText];
NSLog([NSString stringWithFormat:#"%#", entered]);
if(myData && entered)
{
[myArray addObject:entered];
[tableView reloadData];
}
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (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 [myArray 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];
}
cell.textLabel.text = [self.myArray objectAtIndex:indexPath.row];
return cell;
}
/*
// 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;
}
*/
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
[self.list removeObjectAtIndex:row];
[tableView deleteRowsAtIndexPaths:[myArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
As prevoulsy ansewered; self.list has to be Mutable.
The next thing you need to do is "warn" the tableView about the updates.
So you would do it like this:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
[self.list removeObjectAtIndex:row];
//Notice we "warn" the tableView
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
//We also tell the table the updates are done so it can do the proper animations
[tableView endUpdates];
}
Remember you first change the model and then update the tableView with the add, reload and delete methods in between a beginUpdates and endUpdates.
What type is self.list? It needs to be an NSMutableArray for a call to 'removeObjectAtIndex' to be valid.
There is no .plist involved here, that's just the name of this NSMutableArray. Your sample code assumes you are declaring an NSMutableArray called list in your #interface...
#interface RoutineTableViewController : UIViewController {
NSMutableArray *list;
}
#property (nonatomic, retain) NSMutableArray *list;
#end
... and synthesizing it (and filling it with something) somewhere in your code.
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
after this I am increasing the height of the 1st cell in heightforRowAtIndexPath. But to my surprise it is increasing the height of the second cell, but when I scroll the table view... the height of the first one is set back to desired.
If I reload the entire table using [tv reloaddata] it works fine.. does not work only if i do the particular cell
Any help on this would be helpful..
As written in the comments above, I only have a vague understanding about what you want to achieve. I assume you want to extend cell by changing their height. You just mention the first cell, but I guess, you want to be able, to do it for any cell when being clicked.
The complete project is available at github
.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
NSIndexPath *selectedIndexPath;
NSDictionary *articles;
}
#end
.m
#import "FirstViewController.h"
#implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
selectedIndexPath = nil;
articles = [[NSDictionary dictionaryWithObject:[NSArray arrayWithObjects:#"one", #"two", #"three",
#"four", #"five", #"six",
#"seven", #"eight", #"nine",
#"ten", #"eleven", nil]
forKey:#"title"] retain];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[selectedIndexPath release];
[articles release];
[super dealloc];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[articles allKeys] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [[articles allKeys] objectAtIndex : section];
}
- (int)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
id key = [[articles allKeys] objectAtIndex:section];
return [[articles objectForKey : key] count];
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ((selectedIndexPath != nil) && (selectedIndexPath.row == indexPath.row))
return 80.0;
return 40.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * MyIdentifier = #"MyIdentifier";
UITableViewCell * cell = [self.tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
id key = [[articles allKeys] objectAtIndex:indexPath.section];
cell.textLabel.text = [[articles objectForKey:key] objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedIndexPath == indexPath) {
selectedIndexPath = nil;
} else {
selectedIndexPath = indexPath;
}
[self.tableView deselectRowAtIndexPath : indexPath animated : NO];
[tableView beginUpdates];
[tableView endUpdates];
}
#end
This code is quite rough, as I just extracted it from a project in my very early iPhone-days. i.e. properties are missing.