I'm a beginner and I've read everything on StackOverflow about my problem - my app with json data doesn't show anything on TableViewController. I'm probably missing something obvious, but the help is appreciated very very much. (I'm using the latest Xcode 5 DP, if it's important).
TableVC.h
#interface TableVC : UITableViewController <UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) NSDictionary *kinos;
#property (retain, nonatomic) UITableView *tableView;
-(void)fetchKinos;
#end
And the TableVC.m file is
#interface TableVC ()
#end
#implementation TableVC
- (void)viewDidLoad
{
[self fetchKinos];
[self.tableView reloadData];
[super viewDidLoad];
}
-(void)fetchKinos {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.adworldmagazine.com/json.json"]];
NSError *error;
_kinos = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _kinos.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"KinoCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//[self configureCell:cell atIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSArray *entities = [_kinos objectForKey:#"entities"];
NSDictionary *kino = [entities objectAtIndex:indexPath.row];
NSDictionary *title = [kino objectForKey:#"title"];
NSString *original = [title objectForKey:#"original"];
NSString *ru = [title objectForKey:#"ru"];
cell.textLabel.text = original;
cell.detailTextLabel.text = ru;
return cell;
}
#end
Your JSON response dictionary contains an array of entities whose count needs to be returned from the table view method.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self.kinos objectForKey:#"entities"] count];
}
Also, a suggestion, when you declare strong properties, try to access them as self.propertyName instead of accessing the ivar like _propertyName.
Hope that helps!
I accessed your url- http://www.adworldmagazine.com/json.json on my browser.
The response returns a JSON with root: dictionary.
So,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _kinos.count;
}
wont work.
Use this instead:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_kinos objectForKey:#"entities"].count;
}
Related
I have a parsed data from JSON file. It works like a charm in the first view of my UITableView. However, it displays a blank second view when I tap on an item.
MasterView.h
#interface MasterViewController : UITableViewController
{
NSArray *json;
}
#property (nonatomic, retain) NSArray *json;
#end
MasterView.m
#import "MasterViewController.h"
#import "InformationViewController.h"
#interface MasterViewController ()
#end
#implementation MasterViewController
#synthesize json;
- (void)viewDidLoad
{
[super viewDidLoad];
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://j4hm.t15.org/ios/console.php"]];
[self performSelectorOnMainThread: #selector(fetchedData:) withObject: jsonData waitUntilDone: YES];
}
- (void)fetchedData:(NSData *)responseData
{
NSError *error;
self.json = [NSJSONSerialization JSONObjectWithData: responseData options: kNilOptions error: &error];
NSLog(#"String is %#", self.json);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [json 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;
}
cell.textLabel.text = [[json objectAtIndex: indexPath.row] objectForKey: #"Console"];
[cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
InformationViewController *informationViewController = [[InformationViewController alloc] initWithStyle:UITableViewStylePlain];
informationViewController.title = [[json objectAtIndex: indexPath.row] objectForKey: #"Console"];
informationViewController.Information = [[json objectAtIndex: indexPath.row] objectForKey: #"Model"];
NSLog(#"String is %#", informationViewController.Information);
[self.navigationController pushViewController: informationViewController animated:YES];
}
InformationView.h
#interface InformationViewController : UITableViewController
#property (nonatomic, strong) NSArray * Information;
#end
InformationView.m
#interface InformationViewController ()
#end
#implementation InformationViewController
#synthesize Information;
- (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 = [[Information objectAtIndex: indexPath.row] objectForKey: #"Model"];
[cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
Here i Posted Another Answer Just Because i don't want to Generate Confusion.
The Project Code : http://www.cogzentappz.com/demo/iostutorial/TestJson.zip
instead of passing the Selected Value, Pass the Whole Array through NSUsedDefaults And Retrive them Using Following Code.
- (void)fetchedData:(NSData *)responseData
{
NSError *error;
self.json = [NSJSONSerialization JSONObjectWithData: responseData options: kNilOptions error: &error];
NSLog(#"String is %#", self.json);
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *arrayObj = [[NSMutableArray alloc] init];
for(int i = 0 ; i<[self.json count] ; i++) {
[arrayObj addObject:[json objectAtIndex:i]]];
}
[standardDefaults setObject:arrayObj forKey:#"longArray"];
[arrayObj release];
}
In the Next View you can Retrive the data Using the Below method.
in ViewDidLoad of informationViewcontroller use This
//reading
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSArray *arrayObj = [standardDefaults objectForKey:#"longArray"];
for(int i = 0 ; i<[arrayObj count] ; i++) {
NSLog(#"String is %#",[arrayObj objectAtIndex:i]);
}
As per Your Link The Json Output is like Below :
NSArray-->NSDictionary-->NSArray-->NSDictionary-->NSArray-->NSDictionary
Go to the link : http://json.bloople.net and Post all your json output and Hit enter.
So you have to get the values According to that format.
for(int i = 0 ; i<[self.json count] ; i++) {
NSArray *info_Array=[[self.json objectAtIndex:i ]valueForKey:#"Information"];
NSLog(#"info_Array is %#", info_Array);
for(int j = 0 ; j<[info_Array count] ; j++)
{
NSLog(#"Model is %#", [[info_Array objectAtIndex:j ]valueForKey:#"Model"]);
NSArray *title_Array=[[info_Array objectAtIndex:j ]valueForKey:#"Title"];
for(int k = 0 ; k<[title_Array count] ; k++)
{
NSLog(#"Game is %#", [[title_Array objectAtIndex:k ]valueForKey:#"Game"]);
NSLog(#"Publisher is %#", [[title_Array objectAtIndex:k ]valueForKey:#"Publisher"]);
}
}
NSString *Console_string= [[dataArray objectAtIndex:i ]valueForKey:#"Console"];
NSLog(#"String is %#", Console_string);
}
NSString *Console_string= [[self.Json objectAtIndex:i ]valueForKey:#"Console"];
NSLog(#"String is %#", Console_string);
}
I think you have to reloadData after you fetch your data. Right now, you specify that the NSArrray *json is empty, since the count returns 0. Thus, you prohibit the table view from being filled. Call [tableView reloadData]; after you fetch your data.
Change your code of MaterView.m with this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
InformationViewController *informationViewController = [[InformationViewController alloc] initWithStyle:UITableViewStylePlain];
informationViewController.title = [[json objectAtIndex: indexPath.row] objectForKey: #"Console"];
informationViewController.Information = [[json objectAtIndex: indexPath.row] objectForKey: #"Model"];
NSLog(#"String is %#", informationViewController.Information);
[self.navigationController pushViewController: informationViewController animated:YES];
}
Hope it helps you...
I have two UITableview's and if i select a one row in each table, the textLabel.text of that particular row should display in a single UIAlertview.
How can i combine the textLabel.textof two tables and display in one UIAlertView
Can anyone let me know how can i do this
EX: one Table view which displays A, B, C, D and one more tableView Which Shows 1,2,3,4.
This two table are from different class's. now suppose if i press a row in table 1 i will get textLabel.text as 'A' and if i press table 2 i will get textLabel.text as '1' now on the view if a select A in table1 and 1 in table 2 i should get a AlertView showing message as 'A1'
Code for reference:
viewController.h
#import <UIKit/UIKit.h>
#import "FirstTVContoller.h"
#import "SecondTVController.h"
#interface TwoTableViewsViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>{
FirstTVContoller *firstController;
SecondTVController *secondController;
IBOutlet UITableView *firstTable;
IBOutlet UITableView *secondTable;
NSString *stringTable1;
NSString *stringTable2;
NSArray * myArray1;
NSArray * myArray2;
}
#property (nonatomic, retain) NSString *stringTable1;
#property (nonatomic, retain) NSString *stringTable2;
#property (nonatomic, retain) NSArray * myArray1;
#property (nonatomic, retain) NSArray * myArray2;
#end
.m:
#import "TwoTableViewsViewController.h"
#implementation TwoTableViewsViewController
#synthesize stringTable1 = stringTable1;
#synthesize stringTable2 = stringTable2;
#synthesize myArray1,myArray2;
- (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)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (tableView == firstTable) {
self.stringTable1 = [myArray1 objectAtIndex: indexPath.row];
//call uiAlert, and place the stringTable1 on your message
if (tableView == secondTable) {
self.stringTable2 = [myArray2 objectAtIndex: indexPath.row];
//call uiAlert, and place the stringTable2 on your message
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"hi" message:[NSString stringWithFormat:#"%# %#", self.stringTable1, self.stringTable2] delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[firstController release];
[secondController release];
[firstTable release];
[secondTable release];
[stringTable1 release];
[stringTable2 release];
[super dealloc];
}
#end
table1:
#import <Foundation/Foundation.h>
#interface FirstTVContoller : UITableViewController <UITableViewDataSource, UITableViewDelegate>{
NSMutableArray *items;
}
#end
#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
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *stringVariable = cell.textLabel.text;
NSLog(#"%#",stringVariable);
[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
Table2:
#import <Foundation/Foundation.h>
#interface SecondTVController : UITableViewController <UITableViewDataSource, UITableViewDelegate>{
int numberOfCells;
}
#end
#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];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *stringVariable = cell.textLabel.text;
NSLog(#"%#",stringVariable);
}
- (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
Kindly Suggest
Is not clear to me when you want your alertView shown,
but this will help you
you need to have a property for placing the text of your labels
so on your .h
# interface MyViewController :UIViewController {
NSString *_stringTable1;
NSString *_stringTable2;
}
#property (nonatomic, retain) NSString *stringTable1;
#property (nonatomic, retain) NSString *stringTable2;
on your .m
#synthesize stringTable1 = _stringTable1;
#synthesize stringTable2 = _stringTable2;
- (void) dealloc{
[_stringTable1 release];
[_stringTable2 release];
[super dealloc];
}
so on your table delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == table1) {
self.stringTable1 = [myArray1 objectAtIndex: indexPath.row];
//call uiAlert, and place the stringTable1 on your message
}
if (tableView == table2) {
self.stringTable2 = [myArray2 objectAtIndex: indexPath.row];
//call uiAlert, and place the stringTable2 on your message
}
}
when you call your uiAlertView, for the message you can just show them togheter like
[NSString stringWithFormat:#"%# %#", self.stringTable1, self.stringTable2];
//Combine two string in one string on the tap of second table cell tap event...
//Use following code in didSelectRowAtIndexPath method..and enjoy...
NSString *tempstring = [[NSString alloc]init];
tempstring =yourlable.text;// your cell label...
if (textField.tag == 1) {
NSUserDefaults *stringsaver = [NSUserDefaults standardUserDefaults];
if([stringsaver objectForKey:#"stringsaver"]== nil)
{
[stringsaver setObject:tempstring forKey:#"stringsaver"];
}
else
{
NSString *combinedstring = [stringsaver objectForKey:#"stringsaver"];
//NSLog(#"==%#",combinedstring);
UIAlertView *alertdata = [[UIAlertView alloc]
initWithTitle:#"Your Title"
message:combinedstring
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertdata show];
[alertdata release];
[stringsaver removeObjectForKey:#"stringsaver"];
}
Try this-
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell * cell1 = [tableView cellForRowAtIndexPath:indexPath];
// get here the instance of otherTableView.
UITableViewCell * cell2 = [otherTableView cellForRowAtIndexPath:indexPath];
UILabel *Title1 = (UILabel *)[cell1 viewWithTag:1]; //for it you need to make the label with Tag 1
UILabel *Title2 = (UILabel *)[cell2 viewWithTag:1]; //for it you need to make the label with Tag 1
NSString * str = [NSString stringWithFormat:#"%# %#",[Title1 text],[Title2 text]];
//fire the alert
UIAlertView *alertdata = [[UIAlertView alloc]
initWithTitle:#"Your Title"
message:str
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertdata show];
}
I need to implement the abcd list indexing in the below table view right side.when i am clicking on a/b/c etc table view need to show the entries according to that for sorting like iphone contacts .may i know what are all
the changes i need for it.is need to create sections for that?please any one explain me
any solution.
I have an class named as "myClass" which contains the properties iD, name and imageURL.
image url holds the photolibrary alasset url.
myClass.h
#interface myClass: NSObject {
NSInteger iD;
NSString *name;
NSString *imageURL;
}
#property (nonatomic, assign) NSInteger iD;
#property (nonatomic, assign) NSString *name;
#property (nonatomic, assign) NSString *imageURL;
myClass.m
#implementation myClass
#synthesize iD;
#synthesize name;
#synthesize imageURL;
#end
So I added 50 image details with iD, name, imageURL as myClass objects in to an NSMutableArray named as *BundleImagesArray *
i displayed it in a table view. my code is:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
//getting all image details with iD,name,imageURL as **myClass** objects
BundleImagesArray = [staticDynamicHandler getImageFromBundle];
int count = [BundleImagesArray count];
for (int i = 0; i<count; i++) {
//this array for easy scrolling after first time the table is loaded.
[imageCollectionArrays addObject:[NSNull null]];
}
return count;
}
cellForRowAtIndexPath
- (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];
}
//removing all the subviews
if ([cell.contentView subviews]) {
for (UIView *subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell setAccessoryType:UITableViewCellAccessoryNone];
myClass *temp = [BundleImagesArray objectAtIndex:indexPath.row];
//adding image view
UIImageView *importMediaSaveImage=[[[UIImageView alloc] init] autorelease];
importMediaSaveImage.frame=CGRectMake(0, 0, 200,135 );
[cell.contentView addSubview:importMediaSaveImage];
//adding image label
UILabel *sceneLabel=[[[UILabel alloc] initWithFrame:CGRectMake(220,0,200,135)] autorelease];
sceneLabel.font = [UIFont boldSystemFontOfSize:16.0];
sceneLabel.textColor=[UIColor blackColor];
[cell.contentView addSubview:sceneLabel];
sceneLabel.text = temp.name;
if([imageCollectionArrays objectAtIndex:indexPath.row] == [NSNull null]){
//getting photlibrary image thumbnail as NSDAta
NSData *myData = [self photolibImageThumbNailData::temp.imageURL]
importMediaSaveImage.image =[UIImage imageWithData:myData ];
[imageCollectionArrays replaceObjectAtIndex:indexPath.row withObject:importMediaSaveImage.image];
} else {
importMediaSaveImage.image = [imageCollectionArrays objectAtIndex:indexPath.row];
}
temp = nil;
return cell
}
*Note:*
i done it using the following way
1.Number of sections-
inside this we are getting the label array and then calling the method countArrayWords whihc will count the words and
the alphabets starting from a particular word.
2.Title for headerin section-
Used for gettting the headers for the sections.Currently we are not using this methd as it will not look good when we are having
no data on the table view.
3.number of rows in section-
in this we are calling the method countArrayWords if the sectio=0.
4.cell for row at index path-
this is the method in which we are calculating a variable known as h through which we are using to bind the images to the table
view.
However the Tableview performence is too slow with 1000 images
An easy way to handle this is to create 2 arrays, one of sections, and another of section titles. You can then populate these from your sorted array of MyClass'es in your init method (initWithObjects: , say)
- (id) initWithObjects: (NSArray *) myObjectsArray
{
self = [super initWithNibName: <your-nib-name> bundle: nil];
if (self) {
self.sections = [NSMutableArray array];
self.sectionTitles = [NSMutableArray array];
for (MyClass * object in self.myObjectsArray) {
NSMutableArray * section = [self.sections lastObject];
if (!section || ![[[[section lastObject] name] substringToIndex: 1] isEqualToString: [object.name substringToIndex: 1]]) {
// Create a new section on change of first character
[self.sections addObject: [NSMutableArray array]];
[self.sectionTitles addObject: [object.name substringToIndex: 1]];
}
[[self.sections lastObject] addObject: object];
}
}
return self;
}
Then your datasource methods are
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.sections count];
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self.sections objectAtIndex: section] count];
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Create cell
MYClass * object = [[self.sections objectAtIndex: indexPath.section] objectAtIndex: indexPath.row];
//Configure cell
return cell;
}
- (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView
{
return self.sectionTitles;
}
Whenever i scroll my UITableView, it looks at an array to find out what to fill the next cell with, but the array is empty, causing a crash, and appears to have been released somehow. Here is my code:
.h
#interface HomeViewController : UITableViewController {
NSArray *vaults;
}
#property (retain) NSArray *vaults;
#end
.m
#import "HomeViewController.h"
NSString *vaultsPath;
#implementation HomeViewController
#synthesize vaults;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
vaultsPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Vaults"];
NSFileManager *fileManager = [NSFileManager defaultManager];
self.vaults = [fileManager contentsOfDirectoryAtPath:vaultsPath error:nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.vaults 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];
}
NSString *dictionaryPath = [NSString stringWithFormat:#"%#/%#",
vaultsPath,
[self.vaults objectAtIndex:indexPath.row]]; //Crashes at this line, with the self.vaults array now empty.
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:dictionaryPath];
cell = [AHCellCreation createCellWithDictionary:dictionary Cell:cell];
return cell;
}
- (void)dealloc
{
[super dealloc];
[self.vaults release];
}
#end
Any ideas?
My guess is the app crashes when you try to access the value of vaultsPath, which must be deallocated. Because the table view row count is based on the number of elements in the array, the method returning the cells, won't be called if there isn't any element in.
Try to retain the value assigned to vaultsPath, and don't forget to release it later.
i write this code
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
dataToDisplay = [[NSMutableArray alloc] init];
//NSString *myJSON = [[NSString alloc] initWithString:responseString];
NSDictionary *json = [responseString JSONValue];
Status *statut = [[Status alloc] init];
statut.flyNumber = [json objectForKey:#"flynumber"];
statut.ftatuts = [json objectForKey:#"fstatuts"];
statut.escDepart = [json objectForKey:#"escdepart"];
statut.escArrival = [json objectForKey:#"escarrival"];
statut.proArrival = [json objectForKey:#"proarrival"];
statut.proDepart = [json objectForKey:#"prodepart"];
statut.estDepart = [json objectForKey:#"estdepart"];
statut.estArrival = [json objectForKey:#"estarrival"];
statut.realDepart = [json objectForKey:#"realdepart"];
statut.realArrival = [json objectForKey:#"realarrived"];
[dataToDisplay addObject:statut];
NSLog(#"ok");
}
- (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 [dataToDisplay 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];
}
// Configure the cell...
NSLog(#"1 ok");
Status *statut2 = [dataToDisplay objectAtIndex:indexPath.row];
NSLog(#"2 ok");
cell.textLabel.text = [NSString stringWithFormat:#"%# - %#",statut2.flyNumber,statut2.ftatuts];
NSLog(#"3 ok");
return cell;
}
The problem that the table still empty . And i don't have "ok 1" message in the console .
This is my controller .h
#import <UIKit/UIKit.h>
#import "ASIHTTPRequest.h"
#import "JSON.h"
#import "Status.h"
#interface StatusTableViewController : UITableViewController {
NSString * Flynumber;
NSMutableArray *dataToDisplay;
}
#property(retain,nonatomic) IBOutlet NSString * Flynumber;
#end
i added [self.tableView reloadData]; and it work .
But how to put each result on a line (cell) ?
To execute a reload you have to execute :
[self.tableView reloadData];
at the end of the requestFinished: function
provided you have set everything else correctly, would you try and execute a reloadData at the end of - (void)requestFinished:(ASIHTTPRequest *)request?
Does your controller (?) conform to the UITableViewDelegate and UITableViewDataSource protocols?
#interface YourController : UIViewController <UITableViewDelegate, UITableViewDataSource> {...}
If yes, check to make sure you've set the dataSource property. Typically, this is set to self.