I am new in iPhone application development. I am currently working on XML parsing. I am extracting records from an xml file and storing it in an mutable array. I have a table view and i am loading the table view from that mutable array. I get 18 rows in the table view which i found by debugging. The problem is when i scroll down upto 10 rows it moves well but as 10th row appears the app crashes. i get the error of EXC_BAD_ACCESS. Here is my code where the cell gets loaded. Thanks.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
Location *record = [[Location alloc] init];
record = [[parse locationarr] objectAtIndex:indexPath.row];
cell.textLabel.text = record.locationname;
return cell;
}
}
There are some misstakes in the code you post, first you only return a cell is the table isn't return a cell for dequeueing
Thus changing you code likewise will solve that problem:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
Location *record = [[Location alloc] init];
record = [[parse locationarr] objectAtIndex:indexPath.row];
cell.textLabel.text = record.locationname;
return cell;
}
Also having to alloc and init a Location every time is very costly, it's better to have a Location with in the class that you call every time a cell is needed.
Beter yet is to just grab the data for the cell only and not do any lengthy method in the tableVieew:cellForRowAtIndexPath: method.
your mistake is " return cell" which is written in inside the if condition take it outside also row title label text set out side condition.like this way..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
Location *record = [[Location alloc] init];
}
else
{
// get record object here by tag.
}
record = [[parse locationarr] objectAtIndex:indexPath.row];
cell.textLabel.text = record.locationname;
return cell;
}
You need to write this snippet
`record = [[parse locationarr] objectAtIndex:indexPath.row];
cell.textLabel.text = record.locationname;`
out of if block.
Enjoy Programming!!
Related
I am creating a table with three different types of custom cell, One of them, one custom cell is having UITextField. I create two rows using this custom cell. I set tag and delegate for textfields of both row.
My problem is, when I scroll the table, these rows with textfields move up and disappear from the screen, when scroll down, that time my app gets crash.
I get an error like
-[CellImageViewController txtField]: unrecognized selector sent to instance 0xa0ea5e0
Here is my code for cellForRowAtIndexPath:
if (indexPath.row == 0 )
{
if (cell == nil) {
cell = [[[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID] autorelease];
}
cell.txtField.tag =1;
cell.txtField.delegate = self;
cell.txtField.text = #"kjfkd";
}
return cell;
}
else if(indexPath.row==1)
{
if (cell == nil) {
cell = [[[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID] autorelease];
}
cell.txtField.tag = 2;
cell.txtField.text = #"glk";
cell.txtField.delegate = self;
return cell;
}
Any one have idea about this issue?
you have different type of cells, so you need to use a cellIdentifier different for each one.
Try this:
customOrNormalCell *cell [tableView dequeueReusableCellWithIdentifier:CellIdentifier]
if(!cell){
cell = [[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:#"%i", indexPath.row]];
}
With this code, each cellIdentifier will be 1,2,3,4... (All different)
I'm pretty sure that it will solves the problem
create UITextField before create UITableView and Add your Textfield object in cell Content view
[cell.contentView addSubview:yourTxtFieldOblect];
It looks like you might be reusing a cell of a different type.
Try making sure which kind of class the cell you are reusing is before trying to access it's properties.
why you are define cell for each row?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d",indexPath.row];
CellWithTextFieldViewController *cell = (CellWithTextFieldViewController *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell =[[[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]autorelease];
cell.txtField.tag = indexPath.row;
cell.txtField.text = [SET TEXT FROM ARRAY];
cell.txtField.delegate = self;
}
}
I had also faced this problem in my project.
just try this:
Disabled the scrolling property in Tableview and create a scrollview.Then add your Tableview in your scrollview.
UITableView *table=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, 976, 395) style:UITableViewStylePlain];
[table setSeparatorStyle:UITableViewCellSelectionStyleNone];
UIScroll *scroll=[[UIScrollView alloc]initWithFrame:CGRectMake(24, 168, 978, 395)];
[table setScrollEnabled:NO];
[scroll addSubview:table];
[self.view addSubview:scroll];
[scroll sendSubviewToBack:table];
Try this
static NSString *cellIdentifier= #"Cell";
CellWithTextFieldViewController *cell = (CellWithTextFieldViewController *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.txtField.tag =indexPath.row+1;
cell.txtField.delegate = self;
cell.txtField.text = #"kjfkd";
return cell;
While scrolling tableView your cell is getting reused. Thats why textField is disappearing. Try to use different cell id for different custom cells. Dont forget to give the same id in nib file for cell identifier
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customCellOne = #"customCell1";
static NSString *customCellTwo = #"customCell2";
UITableViewCell *cell =nil;
if (0 == indexPath.row)
{
cell = (CustomCellOne *)[tableView dequeueReusableCellWithIdentifier:customCellOne];
if (nil == cell)
{
// Create custom cell one and do what ever you want
}
}
else if (1 == indexPath.row)
{
cell=(CustomCellTwo *)[tableView dequeueReusableCellWithIdentifier:customCellTwo];
if (nil == cell)
{
// Create custom cell two and do what ever you want
}
}
return cell;
}
I don't know,may be when reused the cell,the textfield delegate was released.
may be you can set the
textfield.deleagate = self;
in CellWithTextFieldViewController.m
So I don't know how this is happening, or how to fix it, but I am having an issue of my UISearchDisplayController's plain tableView displaying search results with a grouped cell.
I have a dataSource array with a few names, a tableData array that iterates through the dataSource array and adds any entries that fit the searchText, and then depending on which tableView it is, I reload the tableView with the appropriate dataSource...
Ideas anyone?
Code:
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
int count = 0;
if(aTableView == self.tableView){
count = [userTableData count]==0?1:[userTableData count];
}else{
count = [tableData count];
}
return count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return #"Users";
}
- (UITableViewCell *)tableView:(UITableView *)tView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
if(tView == self.tableView){
if([userTableData count] == 0){
cell.textLabel.text = #"Please select a user";
}else{
cell.textLabel.text = [userTableData objectAtIndex:indexPath.row];
}
}else{
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
}
return cell;
}
And then as the search is entered, matching strings are added to the tableData array
assign tags to the UITableView and hide the grouuped tableView while searching
In the documentation for UISearchDisplayController about the searchResultsTableView property, it says
Discussion:
This method creates a new table view if one does not already exist.
So what you could try is create your own UITableViewwhen you set up the UISDC, explicitly making it plain:
UITableView *searchTableView = [[UITableView alloc] initWithFrame:CGRectZero
style:UITableViewStylePlain];
searchDisplayController.searchResultsTableView = searchTableView;
I have created sample application that insert 12 rows in tableview.And inserted fine.When after inserted my rows i dont want any changes in text during scrolling of tableview.So i checked with indexpath row has value of UITableViewCell , if it has values means return that cell otherwise we created new UITableViewCell.
My sample code is below
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"GlobalCount = %d",GlobalCount);
return GlobalCount;
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *obj = (UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
if(obj!=nil)
{
NSLog(#"cell indexpath row = %d",indexPath.row);
NSLog(#"cell text = %d",obj.textLabel.text);
return obj;
}
else {
NSLog(#"obj==nil");
}
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
if([DataTable count]>0)
cell.textLabel.text = [DataTable objectAtIndex:0];
// Configure the cell.
return cell;
}
What my objective is , i dont want update any text (or UITableViewCell)for already created indexpath rows(of cell).So i can check this in cellForRowAtIndexPath , but it always return nil.If i am missing anything ?
I checked using this line
UITableViewCell *obj = (UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
if(obj!=nil)
Plz help me?
Thanks in advance......
Let the table view decide id it need to update the cell or not. Just remove all the firsdt part of your code and everything will run smoothly.
Don't hesitate to read the UITableView doc.
I have this bizarre problem. I'm making a checklist program with XCode and I'm using UITableView with UITableViewCellAccessoryCheckmark. I can select cells and the checkmark will appear, but somehow, other cells that I have NOT yet selected below will also have a checkmark appear. Any ideas?
Here's my check mark coding:
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
cell = [aTableView cellForRowAtIndexPath: indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
I don't know if this affects it, but I also implemented this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
if(tableView == Table1){
switch(indexPath.section){
case 0:
cell.textLabel.text = [array1 objectAtIndex:indexPath.row];
break;
case 1:
cell.textLabel.text = [array2 objectAtIndex:indexPath.row];
break;
case 2:
cell.textLabel.text = [array3 objectAtIndex:indexPath.row];
break;
}
//cell.textLabel.text = [NSString stringWithFormat:#"Row %d", indexPath.row];
}
if(tableView == Table2){
cell.textLabel.text = [array4 objectAtIndex:indexPath.row];
}
return cell;
}
Thanks.
Set the cell.accessoryType each time you call tableView:cellForRowAtIndexPath:. Otherwise, when you reuse a cell, you'll get it's accessoryView instead of what you're expecting.
So, yeah, you'll need to keep track in when NSIndexPaths are selected by some method other than just looking at the accessoryType.
You should keep the checked/unchecked info in data source (array).
I also advise you to remove the cell.accessoryType = UITableViewCellAccessoryNone; line.
This line will be executed only for few first cells. All the other cells will be "reused" - meaning that the old (already initiated) cells will be used, and you will have to modify the details that are displayed on these cells (all inside cellForRowAtIndexPath as you do now).
In addition you will have to add a similar line (something like cell.accessoryType = ([[array objectAtIndex:indexPath.row] boolValue] ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;).
In general, I suggest you to use one array for holding the data for your table, when each item in the array will be a dictionary. This way you will be able to hold the texts and the boolean checkmarks (inside NSNumber) and easily access them when needed.
I just have a basic (noob) question about cellForRowAtIndexPath get called?
I'm working through example code and I don't see it explicitly called anywhere?
Does any component of type UITableViewComponent automatically call this function when it is created?
Thanks
When a UITableView is displaying this method gets called per row. In it you will customize each cell with particular data for display.
Here's the class reference.
Here's a sample:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"FriendCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
Item *i = [itemArray objectAtIndex:row];
cell.textLabel.text = [i name];
cell.detailTextLabel.text = [i brewery];
[i release];
return cell;
}
This is called for each cell when the corresponding UITableView gets drawn. An index path is passed in, and based on the section and cell numbers, your code should generate a UITableViewCell to be displayed in the UI.
You can look here for a quick tutorial into how UITableViews work.