Null data when loading DetailView - objective-c

I have UITableView I want to click on row and load detail view but I have null information in my Log in detail view
would you please help m win this implementation
Thanks in advance!
cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
//Load Cell for reuse
static NSString *CellIdentifier = #"TestCell";
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell =[ [[NSBundle mainBundle] loadNibNamed:#"TestCell" owner:nil options:nil]
lastObject];
}
_tests = [server info];
_t = [NSMutableString stringWithFormat:#"%# ", [_tests objectAtIndex:indexPath.row]];
NSString *testdata = _t;
_components = [testdata componentsSeparatedByString:#","];
for (NSString *aComponent in _components) {
if ([aComponent hasPrefix:#"titletest"]) {
_subComponents = [aComponent componentsSeparatedByString:#":"];
_testString = [_subComponents[1] stringByTrimmingCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:#"\""]];
}if ([aComponent hasPrefix:#"note"]){
_subComponents = [aComponent componentsSeparatedByString:#":"];
_noteString = [_subComponents[1] stringByTrimmingCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:#"\""]];
break;
}
}
cell.title.text = _testString;
cell.note.text = _noteString;
return cell;
}
didSelectRowAtIndexPath method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
TestDetailView *c = [[TestDetailView alloc] init];
///I don't know what should I put here to c
[self.navigationController pushViewController:c animated:YES];
}
but in My detail view
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
NSLog(#" test : %#",_Info.datas); ==>> my log was (null)
}
My Detail View Header
#property (strong, nonatomic) IBOutlet UILabel *bDetailTitle;
#property (strong, nonatomic) IBOutlet UILabel *bDetailNote;
#property (nonatomic, strong) NSArray *datas;
#property (nonatomic,strong) TestTable *Info;
#end

I'm assuming that TestDetailView is a ViewController subclass and that you have a property on it possibly called datas. If that is the case you appear to create your detail view controller in didSelectRowAtIndexPath: like this:
TestDetailView *c = [[TestDetailView alloc] init];
But then immediately change it the pointer to something else (possibly nil):
c = [_datas objectAtIndex:indexPath.row];
objectAtIndex returns an id which means your code probably doesn't throw a warning in Xcode, but at run time if [_datas objectAtIndex:indexPath.row] does not return a UIViewController (and I suspect that it does not) your app could crash. If it is not throwing an error or crashing you possibly have another problem in that _datas is nil in your parent view controller.
It is a very common technique to pass values to view controllers I would recommend reading up on how to do this. This type of question has been asked on S.O. many times:
How to set value for NSString in another view controller from one viewcontroller

Related

didSelectRowAtIndexPath really doesn't work

The didSelectRowAtIndexPath not working.
Have I configured the 2 delegates. Everything is linked (tableview, tableviewcell).
Already deleted and did it again.
I searched for everything here and nothing worked.
I think this was one of the best link, still to no avail.
My last hope is that it is, I'm opening my ViewController, where has this tableview, for modal. But it would be VERY wrong the problem.
Other than that, I need some help
Somo codes .H
#interface simulator : UIViewController <UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate>
{
NSArray *array_products;
}
#property (nonatomic, strong) NSDictionary *plist_products;
#property (nonatomic, strong) IBOutlet UITableView *table_menu_left;
#property (nonatomic, strong) NSString *file_plist;
#end
Some codes .M
#import "cel_products.h"
- (void)viewDidLoad
{
NSString *path_root = [[NSBundle mainBundle] bundlePath];
NSString *full_path = [path_root stringByAppendingPathComponent:self.file_plist];
self.plist_products = [[NSDictionary alloc] initWithContentsOfFile:full_path];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"id_cell_products";
UITableViewCell *cell = [self.table_menu_left dequeueReusableCellWithIdentifier:CellIdentifier];
array_products = [self.plist_produtcs allKeys];
if (cell == nil)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"cel_products" owner:self options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[cel_products class]])
{
cell = (cel_products *)currentObject;
break;
}
}
}
cell.textLabel.text = [array_products objectAtIndex:indexPath.row];
return cell;
}
// numberofrowsinsection - OK
// numberofsectionintableviw - OK
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Hein?????");
// Nothing..........
}
I humbly thousand apologies to all!
I inadvertently clicked Attributes Inspector> Selection: NO SELECTION
So I do not find anything in the code.
Again, I apologize to everyone, but if someone, are having this problem, this is one more step to be verified. " Change to Attributes Inspector> Selection: SINGLE SELECTION or MULTIPLE SELECTION ( is up to you )
Thanks all for the answers and help
Did you set a break at didSelectRowAtIndexPath? Try and see if it breaks successfully there.
Expanding on rokjark's answer you have to manually set the delegate and data source to the file in question.
Your header file simulator.h simply declares it as A delegate/data source for SOME UITableView.
You still need to point table_menu_left to use simulator.h as THE delegate file to handle all of it's callbacks.
Set:
self.table_menu_left.delegate = self;
self.table_menu_left.datasource = self;
And again set a break in didSelectRowAtIndexPath and see if it gets called.

Multiple tableview issue

I have implemented a view controller with a table view controll called ligatable. This table view has its delegate in a table view controller called ligaViewController.h. Table view control has implemented one prototype cell, that has set ligaCell.h controller. Here are the details:
competicionViewController.h
#import "ligaViewController.h"
#interface CompeticionViewController : UIViewController
{
IBOutlet UITableView *ligaTable;
ligaViewController *ligaController;
}
#property (strong, nonatomic) IBOutlet UITableView *ligaTable;
#property (strong, nonatomic) ligaViewController *ligaController;
competicionViewController.h
- (void)viewDidLoad
{
...
ligaController = [[ligaViewController alloc] init];
[ligaTable setDelegate:ligaController];
[ligaTable setDataSource:ligaController];
....
And the delegate method in ligaViewController:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ligaCell *cell = [self.tableView
dequeueReusableCellWithIdentifier:#"posicion"];
NSDictionary *posicion = [[NSDictionary alloc] initWithDictionary: [ligaArray objectAtIndex:indexPath.row]];
cell.posicion.text = [posicion valueForKey:#"posicion"];
cell.PJ.text = [posicion valueForKey:#"pj"];
cell.PG.text = [posicion valueForKey:#"pg"];
cell.PP.text = [posicion valueForKey:#"pp"];
cell.PF.text = [posicion valueForKey:#"favor"];
cell.PC.text = [posicion valueForKey:#"contra"];
return cell;
}
It is currently giving me this error:
terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
Many thanks
Use -
ligaCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"posicion"];
if (cell == nil)
{
cell = [[[ligaCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CustomCellIdentifier] autorelease];
}

How does a table view controller communicate with its detail view?

I have a table view, and if a certain row is tapped, the detail view will show up. But how does the detail view know which row was tapped ?
So for instance, I have a MainController which displays names. If I tap "Johnny" The next screen should show a label with the string "Johnny". How would I do that ?
[EDIT - Added code]
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ArticleView *article = [self.storyboard instantiateViewControllerWithIdentifier:#"ArticleView"];
[article.myLabel setText:#"random"];
[self.navigationController pushViewController:article animated:YES];
}
- (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];
}
NSDictionary *info = [json objectAtIndex:indexPath.row];
cell.textLabel.text = [info objectForKey:#"username"];
cell.textLabel.backgroundColor = nil;
cell.textLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.backgroundColor = nil;
cell.detailTextLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.text = [info objectForKey:#"user_pic"];
// Configure the cell...
return cell;
}
ArticleView.h
#interface ArticleView : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *myLabel;
#end
ArticleView.m
-> Synthesizing properties
You could pass a object (i.e. the String Jonny) to the detail view controller as a property.
#interface ArticleViewController : UIViewController
#property (retain) ArticleView *articleView;
#end
//Don't forget to synthesize name
in the tableview controller
-(void)tableView:(UITableView *)tableview didSelectRowAtIndexPath:(NSIndexPath)indexPath
{
NSDictionary *info = [json objectAtIndex:indexPath.row];
ArticleViewController *articleViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"ArticleViewController"];
articleViewController.articleView = articleView;
[self.navigationController pushViewController: articleViewController animated:YES];
}
the table view delegate has the method tableView:didSelectRowAtIndexPath:, in this method you present your detail view so you know which row was selected from the indexPath parameter and can pass any info you need when you create the new view controller
Assuming you're talking iPhone here, I would have a property name on my detail view:
#propery (nonatomic, retain) NSString * name;
and an init method as follows:
- (id) initWithName: (NSString *) name
{
self = [super initWithNibName: #"<view-controller-nib-name>" bundle: nil];
if (self) {
self.name = name;
}
return self;
}
and then set name label in viewDidLoad
In the tableView:didSelectRowAtIndexPath: method, get the name referenced by the index path, create and init a detail view controller using initWithName:, then push on the nav stack.

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;

Custom UITableView not refreshing cells

I am creating a custom UITableViewCells. I am using a NIB file as the cell. Its displaying some data from REST API's. The problem I am having is when I scroll down & then back up, the cells are not refreshed. It shows the data from when I scrolled down. Here's my code -
MyViewController.h
#interface FLOViewController : UIViewController <UISearchBarDelegate,
UITableViewDelegate,
UITableViewDataSource>
{
UISearchBar *sBar;
UITableView *searchResTable;
NSArray *searchRes;
UITableViewCell *resultsOne;
}
#property (nonatomic, retain) IBOutlet UILabel *photos;
#property(nonatomic, retain) IBOutlet UITableView *searchResTable;
#property (nonatomic, retain) NSArray *searchRes;
/* Search Results Templates */
#property (nonatomic, assign) IBOutlet UITableViewCell *resultsOne;
MyViewController.m
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(self.searchRes == nil)
return nil;
static NSString *cId = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cId];
if(cell == nil)
{
NSLog(#"CREATING NEW CELL");
[[NSBundle mainBundle] loadNibNamed:#"ResultsOne" owner:self options:nil];
cell = self.resultsOne;
self.resultsOne = nil;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//from here on displaying images etc from REST API.
UIImageView *uPhoto = (UIImageView *)[cell viewWithTag:2];
NSString *photoURL = [[self.searchRes objectAtIndex:[indexPath row]] objectForKey:#"originator_photo_url"];
if(photoURL)
{
[UIView beginAnimations:#"fadeIn" context:NULL];
[UIView setAnimationDuration:0.5];
NSString *urlString = [NSString stringWithString:photoURL];
[uPhoto setImageWithURL:[NSURL URLWithString:urlString]
placeholderImage:[UIImage imageNamed:[NSString stringWithFormat:#"ph%d.png",[indexPath row]]]];
[UIView commitAnimations];
}
//similarly display other sections in the cell...
Why are the contents of my cell not refreshing? Even when I put in completely new data (through search from REST API's) some of the cells still show old views in the tablecells.
UPDATE: If I comment out UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cId]; then the problem is solved. i.e. I dont see repetition of cell content on scrolling.
Because I am creating custom ImageViews in UITableViewCell do i need to do something special to clear out the cell content before new content can be added??
To me it looks like you forgot to reset the uPhoto-UIImageView, in case the photoURL is nil. This brings in cached data.
if (photoURL) {
...
}
else {
uPhoto.image = nil;
}
You are using
static NSString *cId = #"Cell";
Let's try different identifier for each cell. I face this problem and solve it by using different cell identifier like
static NSString *cId =[NSString StringWithFormat : #"Cell_%d_%d",[indexPath section], [indexPath row] ];
I think it may solve your problem.