In tableView I have a few objects that are showing up just fine. However when I interact with the list and scroll down (forward) the app will crash. I have never seen this before and am not aware of why this is happening. I am using a 3rd party calendar in combination with my code, I figured I should mention this but I do not see this being the main issue.
#import "VRGViewController.h"
#interface VRGViewController ()
#end
#implementation VRGViewController{
NSArray *calendarTableData;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
VRGCalendarView *calendar = [[VRGCalendarView alloc] init];
calendar.delegate=self;
calendar.center = self.view.center;
[self.view addSubview:calendar];
calendarTableData = [NSArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto",nil];
}
-(void)calendarView:(VRGCalendarView *)calendarView switchedToMonth:(int)month targetHeight:(float)targetHeight animated:(BOOL)animated {
if (month==[[NSDate date] month]) {
NSArray *dates = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:5], nil];
[calendarView markDates:dates];
}
}
-(void)calendarView:(VRGCalendarView *)calendarView dateSelected:(NSDate *)date {
NSLog(#"Selected date = %#",date);
}
#pragma mark - User Defined Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [calendarTableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"Services";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [calendarTableData objectAtIndex:indexPath.row];
return cell;
}
#end
You have to declare your datasource the following way:
calendarTableData = [[NSArray alloc]initWithObjects:#"Egg Benedict",
#"Mushroom Risotto",nil];
The issue was coming from how I was calling my array.
Since I was using 3rd party code I had disable ARC. Which was causing my issue with how I was calling my array of objects. Thank you to #meda for helping provide me with the answer - after I implemented it I then realized where I was wrong
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to display content in my UITableView in my UIViewController.
My table view is in a regular view called todayView which is in a UIViewController called Calendar
I connected the datasource and delegate to Calendar and added all of the methods for table view, but it still doesn't work.
Currently, my code looks like this
Is there anything I am doing wrong?
#implementation SecondViewController {
NSMutableArray *tableData;
}
-(BOOL)prefersStatusBarHidden{
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMMM dd, yyyy"];
NSString *dateString = [dateFormatter stringFromDate:today];
self.dateLabel.text = dateString;
Event *e1 = [[Event alloc] init];
e1.name = #"All School Mass";
e1.time = #"All Day";
[tableData addObject:e1];
Event *e2 = [[Event alloc] init];
e2.name = #"Tennis - Moreau Catholic vs James Logan";
e2.time = #"4:00 pm at Moreau Catholic";
[tableData addObject:e2];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell == nil)
{
//Create your cell
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Configure your cell
Event *event = [tableData objectAtIndex:indexPath.row];
cell.textLabel.text = event.name;
return cell;
}
Have you initialized that tableData mutable Array ?
i think you hav'nt initialized it thats why its all happening.
Please allocate it
tableData= [NSMutableArray array];
than add some objects .
otherwise tableData.count will return always zero.
so no data will be display.
You may forget this method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
you can implement it and return 1.
I've made a UITableView in my ViewController. In this table view I want to add my data from NSMutableArray, but it does not seem to add the data. Any ideas?
This is the code I'm using.
- (void)viewDidLoad
{
scoreArray = [[NSMutableArray alloc] init];
NSDictionary *myVehicle = [[NSDictionary alloc] initWithObjectsAndKeys:#"Escape", #"name", #"SUV", #"type", nil];
[scoreArray addObject:myVehicle];
[super viewDidLoad];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = [[scoreArray objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.detailTextLabel.text = [[scoreArray objectAtIndex:indexPath.row] objectForKey:#"type"];
return cell;
}
Based on your code you should be able to see one row. But here with no details, the problem is quite difficult to be identified.
Anyway, verify the following:
Does the datasource (and delegate) is set? This is done via XIB or by code?
Did you implement - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section correctly?
Sample
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [scoreArray count];
}
The method - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView should be implemented if you need a number of sections greater than 1. By default returns one.
In addition, I would modify a little bit the viewDidLoad method like the following.
- (void)viewDidLoad
{
[super viewDidLoad]; // call it before any further initialization
scoreArray = [[NSMutableArray alloc] init];
NSDictionary *myVehicle = [[NSDictionary alloc] initWithObjectsAndKeys:#"Escape", #"name", #"SUV", #"type", nil];
[scoreArray addObject:myVehicle];
}
Make sure your .h file indicates that this is the delegate for the UITableView:
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
Also make sure you implement the required datasource methods. In addition to what you have, you must have these:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
and
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [scoreArray count];
}
I have this arquivo.plist below.
I looked at Apple's documentation, but I could not find how to make the listing look and I hope someone can help me.
In the first UITableView, I make a list of names present in arquivo.plist using the following code and loading the following method below.
What I'm trying to do is: When the user clicks on a tableView name, he is taken to a second screen with a new tableView that will display the "frams" of that user.
The problem is that the code I'm using to select the "frams" is the same code that I am using for listing the names on the first screen, but it is not working, because each user has only one name, but it has several "frams".
When I try to implement this, I can even assemble the array with the "frams" and pass using segue (i'll show the array with an NSLog), but this array can not be displayed as a tableView for an error that Xcode is giving me:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary length]:
unrecognized selector sent to instance 0x8b87a60'
The code from the fist view (ViewController.m) is below the contatos.plist
I hope you understand what I'm trying to do and bring me a light!
Thank you all!
a screenshot of the .plist file is bellow:
http://img268.imageshack.us/img268/7356/jl26.png
For reference and for you to better understand the issue, when the user clicks on a table name, an array is generated with "frams" this patient (patients have on average 3 frams each). The Array NSLog that it should be passed to the other page and comport a new table generates the following text:
12/12/2013 16:10:13.513 rer [24251:70 b] (
{
1 = 11;
2 = 12;
3 = 13;
}
I think that's where the problem lies, because this method of Array can not be implemented in a TableView, so I look a light of a better way to mount this array and select frams when I click a patient
So here is my ViewController.m:
#import "ViewController.h"
#import "Contato.h"
#import "perfilViewController.h"
#interface ViewController ()
-(void) loadContacts;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadContacts];
}
-(void) loadContacts
{
NSString *plistCaminho = [[NSBundle mainBundle] pathForResource:#"contatos"
ofType:#"plist"];
NSDictionary *pl = [NSDictionary dictionaryWithContentsOfFile:plistCaminho];
NSArray *dados = [pl valueForKey:#"contatos"];
contatos = [[NSMutableArray alloc] init];
for (NSDictionary *item in dados) {
NSString *nome = [item valueForKey:#"nome"];
NSString *telefone = [item valueForKey:#"telefone"];
NSString *fram = [item valueForKey:#"fram"];
Contato *c = [[Contato alloc] initWithNome:nome andTelefone:telefone andFram:fram];
[contatos addObject:c];
}
}
#pragma mark UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return contatos.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CelulaContatoCacheID = #"CelulaContatoCacheID";
UITableViewCell *cell = [self.tabelaContatos dequeueReusableCellWithIdentifier:CelulaContatoCacheID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CelulaContatoCacheID];
}
Contato *contato = [contatos objectAtIndex:indexPath.row];
cell.textLabel.text = contato.nome;
return cell;
}
#pragma mark -
#pragma mark UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Contato *contato = [contatos objectAtIndex:indexPath.row];
NSString *msg = [NSString stringWithFormat:#"Fram:%#",contato.fram];
fran = [[NSMutableArray alloc] init];
fran = [NSMutableArray arrayWithObject:contato.telefone];
NSLog(#"finalmente eu consegui essa porra!!!%#", fran);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Contato"
message:msg
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[self.tabelaContatos deselectRowAtIndexPath:indexPath animated:YES];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"vai"]) {
NSIndexPath *indexPath = [self.tabelaContatos indexPathForSelectedRow];
perfilViewController *destViewController = segue.destinationViewController;
Contato *contato = [contatos objectAtIndex:indexPath.row];
fran = [[NSMutableArray alloc] init];
fran = [NSMutableArray arrayWithObject:contato.fram];
destViewController.frans = fran;
NSLog(#"%#%#", fran, destViewController.frans);
}
}
#end
I'd firstly do:
//declare NSDictionary *pl; in the ViewController.h
pl = [NSDictionary dictionaryWithContentsOfFile:plistCaminho];
Then to display Names, i'd simply use the dictionary as such:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[pl objectForKey:#"contatos"] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//...
//following commented line not needed anymore
//Contato *contato = [contatos objectAtIndex:indexPath.row];
cell.textLabel.text = [[[pl objectForKey:#"contatos"]
objectAtIndex:indexPath.row]
objectForKey:#"nome"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//following commented line not needed anymore
//Contato *contato = [contatos objectAtIndex:indexPath.row];
//NOTE: fran is a dictionary now
//change "fran" declaration in the ViewController.h to
//NSDictionary *fran;
fran = [[NSDictionary alloc] init];
fran = [[pl objectForKey:#"contatos"]
objectAtIndex:indexPath.row];
NSLog(#"finalmente eu consegui essa porra!!!%#", fran);
//...
//don't deselectRow (the indexPathForSelectedRow will not work correctly later)
//[self.tabelaContatos deselectRowAtIndexPath:indexPath animated:YES];
}
then on -prepareForSegue i'd pass the dictionary associated with the selected row:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"vai"]) {
NSIndexPath *indexPath = [self.tabelaContatos indexPathForSelectedRow];
perfilViewController *destViewController = segue.destinationViewController;
//following commented line not needed anymore
//Contato *contato = [contatos objectAtIndex:indexPath.row];
//NOTE: fran is a dictionary now
//change "fran" declaration in the ViewController.h to
//NSDictionary *fran;
fran = [[NSDictionary alloc] init];
fran = [[[pl objectForKey:#"contatos"]
objectAtIndex:indexPath.row]
objectForKey:#"fram"];
//NOTE: destViewController.frans should be a dictionary
//handle it appropriately
destViewController.frans = fran;
}
}
so basically, all dictionary use, no need for Contato *contato at all.
EDIT: As for your current method, you would be better off replicating the same structure.
As in:
[array of names] has {dictionary with user details} having a key that has {dictionary of frams}
I'd recommend you not using a dictionary to store your Fram values, use an array instead.
This way, you can get the Fram values like this:
for (NSDictionary *item in dados) {
NSString *nome = [item valueForKey:#"nome"];
NSString *telefone = [item valueForKey:#"telefone"];
NSArray *fram = [item valueForKey:#"fram"];
Contato *c = [[Contato alloc] initWithNome:nome andTelefone:telefone andFram:[fram objectAtIndex:index]];
[contatos addObject:c];
}
Where index is an integer variable you'll have to work out how to handle.
PS: be a little more polite when logging you app ;)
I just started learning Xcode, read the book and now trying to implement what I read. The app needs to store certain data in arrays and dictionary, then table view extracts the data by automatically counting number of sections, number of rows and populating table cells with content, assigned to a key word.
Please, see my code, because I've been trying to run the app, but it gives me SIGABRT error. I don't know if new Xcode doesn't declare or call things this way(my book is for iOS3). I tried to find solutions from blogs, youtube, but the app is still not running at this point.
I know that I declared everything correctly in AppDelegate files, etc, because I used someone's sample code of one 1 array. And the table view got populated.
Help me, because something is wrong with my code with NSMutableDictionary and indexPath. Thank you!
#import "TableViewController.h"
#implementation TableViewController
#synthesize tableData;
#synthesize tableSections;
#pragma mark - View lifecycle
- (void)viewDidLoad
{ [self createData];
[super viewDidLoad];
}
-(void)createData{
NSMutableArray *category1;
NSMutableArray *category2;
category1=[[NSMutableArray alloc] init];
category2=[[NSMutableArray alloc] init];
tableSections=[[NSMutableArray alloc] initWithObjects:#"Category 1", #"Category 2", nil];
tableData=[[NSMutableArray alloc] initWithObjects:category1, category2, nil];
[category1 addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"TitleA", #"name",#"A",#"property", nil]];
[category1 addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"TitleB", #"name",#"B",#"property", nil]];
[category2 addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"TitleC", #"name",#"C",#"property", nil]];
[category2 addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"TitleD", #"name",#"D",#"property", nil]];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [tableSections count];
//return [self.tableSections count]; Also tried to use with self. Don’t know which one is correct
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self.tableSections objectAtIndex:section] 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];
}
cell.textLabel.text = [[[tableData objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] objectForKey:#"name"];
/* Also tried this:
tableData *cellObj = [[self.tableData objectAtIndex:indexPath.section]objectAtIndex:indexPath.row];
cell.textLabel.text = cellObj.name;
/* Also tried this:
tableData *cellObj= [[[self.tableData objectAtIndex:indexPath.section]objectAtIndex:indexPath.row]objectForKey:#"name"];
cell.textLabel.text=smsObj.name; */
/* Also tried this:
NSDictionary *item = (NSDictionary *)[self.tableData objectAtIndex:indexPath.row];
cell.textLabel.text = [item objectForKey:#"name"];*/
/* Also tried this way:
NSDictionary *dictionary = [tableData objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"name"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.text = cellValue;
And the same way, but switched order of NSArray and NSDictionary*/
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// This I will add later, after I make my Table View Controller work
}
#end
I know I'm doing something very silly with the codes, but I'm trying to understand the right way to write the codes...
[category1 addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"TitleA", #"name",#"A",#"property", nil]];
[category1 addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"TitleB", #"name",#"B",#"property", nil]];
[category2 addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"TitleC", #"name",#"C",#"property", nil]];
[category2 addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"TitleD", #"name",#"D",#"property", nil]];
}
add this code after initilization of those arrays and try
I'm a beginning programmer. And I had a question.
I currently have a Table View in my app. There are three rows to it, History, Theory, and Applied Use. I would like each one to go to a different detail view. However, each one only clicks to one of the detail views.
I think the issue is at
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"Magnets_AU_Aubrey" bundle:[
Please help any. The three XIB's are Magnets_AU_Aubrey, Magnets_History_Aubrey, and Magnets_Theory_Aubrey
#import "DisclosureButtonController.h"
#import "NavAppDelegate.h"
#import "DisclosureDetailController.h"
#import "DetailViewController.h"
#implementation DisclosureButtonController
#synthesize list;
- (void)viewDidLoad {
NSArray *array = [[NSArray alloc] initWithObjects:#"History", #"Theory", #"Applied Use", nil];
self.list = array;
[array release];
[super viewDidLoad];
}
- (void)viewDidUnload {
self.list = nil;
[childController release], childController = nil;
}
- (void)dealloc {
[list release];
[childController release];
[super dealloc];
}
#pragma mark -
#pragma mark Table Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [list count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * DisclosureButtonCellIdentifier =
#"DisclosureButtonCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
DisclosureButtonCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:DisclosureButtonCellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
NSString *rowString = [list objectAtIndex:row];
cell.textLabel.text = rowString;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
[rowString release];
return cell;
}
#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"Magnets_AU_Aubrey" bundle:[
NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
}
- (void)tableView:(UITableView *)tableView
accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
if (childController == nil) {
childController = [[DisclosureDetailController alloc] initWithNibName:#"MagnetsAubreyCreditsDisclosureDetail" bundle:nil];
}
childController.title = #"Disclosure Button Pressed";
NSUInteger row = [indexPath row];
NSString *selectedMovie = [list objectAtIndex:row];
NSString *detailMessage = [[NSString alloc]
initWithFormat:#"School",selectedMovie];
childController.message = detailMessage;
childController.title = selectedMovie;
[detailMessage release];
[self.navigationController pushViewController:childController animated:YES];
}
#end
NSArray *array = [[NSArray alloc] initWithObjects:#"History", #"Theory", #"Applied Use", nil];
Now do the same for xibs. Create array and fill it with xib names. Then in didSelectRowAtIndexPath to get correct xib name apply the same logic as you do in cellForRowAtIndexPath for getting cell text.