uitableview row render strange behavior - iphone

I want two create 2 sections uitableview
so I did the following code
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(#" I entered numberOfSectionsInTableView");
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section = 0 ) {
1;
}
else {
9;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(#" I entered cellForRowAtIndexPath");
NSLog(#"the Caf files count is : %d",[self.CafFileList count] );
NSLog(#" the txt file %d",[self.TXTFileList count] );
if (indexPath.section == 0 ) { // Enter here twice , even I say it contain only one row
NSLog(#"////////////////////////Section 0 %d" , [indexPath row] );
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[[cell textLabel] setText:[self.TXTFileList objectAtIndex:[indexPath row] ] ];
return cell;
}
else if (indexPath.section == 0 && indexPath.row < [self.TXTFileList count] ){
NSLog(#"////////////////////////Section 1 %d" , [indexPath row] );
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[[cell textLabel] setText:[self.CafFileList objectAtIndex:[indexPath row]] ];
return cell;
}
}
the problem is that it Enter here twice , even I say it contain only one row
if (indexPath.section == 0 ) {
any idea how to solve that

You don't return row numbers in numberOfRowsInSection, you just enter a number, but return nothing.
Also,
if (section = 0 ) {
sets section to 0, you want to use the == operator.

if (section == 0 ) {
return 1;
}
else {
return 9;
}
Also your code:
else if (indexPath.section == 0 && indexPath.row < [self.TXTFileList count] ){
You never generate cell for section == 1. seem will crash or wrong reusing cell

Related

How to Show UITableViewCellAccessoryCheckmark

I have a tableview which has a list of options the user has selcected( It is an edit page ).
the tableview looks as below
Apple UITableViewCellAccessoryCheckmark
Orange UITableViewCellAccessoryNone
Pineapple UITableViewCellAccessoryCheckmark Banana
UITableViewCellAccessoryNone
- (void)viewDidLoad {
self.mySavedFruitsArray = [myDBOperations getMyFruitsList:[appDelegate getDBPath]:self.myId];
}
/ Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
//-------------------------------------------------------------------------------
{
static NSString *CellIdentifier = #"PoemTypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"MyIdentifier"]autorelease];
}
NSDictionary *aDict = [self.myFruitsArr objectAtIndex:indexPath.row];
NSString *aValue = [aDict objectForKey:#"value"];
NSString *aId = [aDict objectForKey:#"key"];
cell.textLabel.text = aValue;
cell.accessoryType = UITableViewCellAccessoryNone;
NSDictionary *aSavedDict = [self.mySavedFruitsArray objectAtIndex:indexPath.row];
NSString *Value = [aSavedDict objectForKey:#"value"];
NSString *Id = [aSavedDict objectForKey:#"key"];
if ( aId == Id ){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
mySavedFruitsArray - it holds the user selected fruits.
myFruitsArr - this has common list of fruits
now i would like to know how to display UITableViewCellAccessoryCheckmark for cell which matches with mySavedFruitsArray.
I mean , in this edit view i want to display the fruits list with user selected option.
Pls let me know how to do that.
I tried like this, but no use.
/ Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
//-------------------------------------------------------------------------------
{
static NSString *CellIdentifier = #"PoemTypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"MyIdentifier"]autorelease];
}
NSDictionary *aDict = [self.myFruitsArr objectAtIndex:indexPath.row];
NSString *aValue = [aDict objectForKey:#"value"];
NSString *aId = [aDict objectForKey:#"key"];
cell.textLabel.text = aValue;
cell.accessoryType = UITableViewCellAccessoryNone;
NSDictionary *aSavedDict = [self.mySavedFruitsArray objectAtIndex:indexPath.row];
NSString *Value = [aSavedDict objectForKey:#"value"];
NSString *Id = [aSavedDict objectForKey:#"key"];
if ( aId == Id ){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
pls note self.mySavedFruitsArray may not be equal to myFruitsArr always ( because user may select only one fruit).
if ( aId == Id ){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
string comparison is wrong. You should compare strings this way:
if([aId isEqualToString:Id]) {
....
}
instead of checking if ( aId == Id ) which compares the strings as identical objects,
use if ([aID isEqualToString:Id]) which compares strings
In a version downloaded yesterday (6/8/14), UITableViewCellAccessoryCheckmark and UITableViewCellAccessoryNone is not valid. It was throwing compiler errors for me. I think you are supposed to use it as an enum, like so:
if item.completed {
cell!.accessoryType = UITableViewCellAccessoryType.Checkmark
} else {
cell!.accessoryType = UITableViewCellAccessoryType.None
}
With this change, my code compiles and the behavior appears in the simulator.
Sorry I don't know which version to look up (UIKit?), I'm new to iOS development.

indexPath.row-1 is 4294967295

I have an indexPath.row that is 1 and logs 1(when using NSLog). If I call indexPath.row-1 (should return 0) it returns 4294967295.
I'm trying to return an objectAtIndex:indexPath.row-1 but that's when I get 4294967295.
Any ideas?
- (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...
Singleton *singleton = [Singleton sharedSingleton];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([[prefs objectForKey:#"isYes"]boolValue] == 1 && randomMarker != 100)
{
//sets cell image
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,98,100)];
imgView.image = [UIImage imageNamed:#"stackoverflow.png"];
cell.imageView.image = imgView.image;
//sets cell text
cell.textLabel.text = #"Text";
self.checkedInCount == 100;
}
else if ([[prefs objectForKey:#"isYes"]boolValue] == 1 && randomMarker == 100)
{
//gets cell and cleans up cell text
NSLog(#"%#", indexPath.row);
NSString *title = [[[singleton linkedList]objectAtIndex:(indexPath.row-1)]objectForKey:#"desc"];
When you attempt to give an unsigned int (NSUInteger) a negative value, it often returns a very large positive value instead.
You are calling
NSString *tempDesc = [[[singleton linkedList]objectAtIndex:indexPath.row-1]objectForKey:#"desc"];
when indexPath.row has value 0, so the translation is:
NSString *tempDesc = [[[singleton linkedList]objectAtIndex:-1]objectForKey:#"desc"];
Since objectAtIndex: takes an unsigned integer as its parameter, -1 is converted to a garbage value of 4294967295.
To avoid this problem, don't subtract 1 from 0 by checking first that indexPath.row is positive.
Here's another problem:
NSLog(#"%#", indexPath.row);
This should instead read:
NSLog(#"%u", indexPath.row);
NSLog(#"%#", indexPath.row);
You shold use %d for integer as indexPath.row will return an integer
Use
NSLog(#"%d", indexPath.row);

When empty field comes, removed the row in the Grouped Table view in iPhone?

I have displayed the datas in grouped table view. The data's are displayed in the table view from XML parsing. I have 2 section of the table view, the section one has three rows and section two has two rows.
section 1 -> 3 Rows
section 2 - > 2 Rows.
Now i want to check, if anyone of the string is empty then i should remove the empty cells, so i have faced some problems, if i have removed any empty cell, then it will changed the index number. So how can i check, anyone of the field is empty?, Because some times more number of empty field will come, so that the index position will be change. So please send me any sample code or link for that? How can i achieve this?
Sample code,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0) {
if([userEmail isEqualToString:#" "] || [phoneNumber isEqualToString:#" "] || [firstName isEqualToString:#" "])
{
return 2;
}
else {
return 3;
}
}
if (section == 1) {
if(![gradYear isEqualToString:#" "] || ![graduate isEqualToString:#" "]) {
return 1;
}
else
{
return 2;
}
return 0;
}
Please Help me out!!!
Thanks.
As per my understanding, you dont want to add the row where data is empty, so ill suggest you should perpare the sections data before telling the table view about the sections and rows.
So, may be following code can help you..., i have tested it you just need to call the method "prepareSectionData" from "viewDidLoad" method and define the section arrays in .h file.
- (void) prepareSectionData {
NSString *userEmail = #"";
NSString *phoneNumber = #"";
NSString *firstName = #"";
NSString *gradYear = #"";
NSString *graduate = #"";
sectionOneArray = [[NSMutableArray alloc] init];
[self isEmpty:userEmail]?:[sectionOneArray addObject:userEmail];
[self isEmpty:phoneNumber]?:[sectionOneArray addObject:phoneNumber];
[self isEmpty:firstName]?:[sectionOneArray addObject:firstName];
sectionTwoArray = [[NSMutableArray alloc] init];
[self isEmpty:gradYear]?:[sectionTwoArray addObject:gradYear];
[self isEmpty:graduate]?:[sectionTwoArray addObject:graduate];
}
-(BOOL) isEmpty :(NSString*)str{
if(str == nil || [[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0)
return YES;
return NO;
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section == 0){
return [sectionOneArray count];
} else if (section == 1) {
return [sectionTwoArray count];
}
return 0;
}
// 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] autorelease];
}
// Configure the cell.
if(indexPath.section == 0){
cell.textLabel.text = [sectionOneArray objectAtIndex:indexPath.row];
} else if (indexPath.section == 1) {
cell.textLabel.text = [sectionTwoArray objectAtIndex:indexPath.row];
}
return cell;
}
#Pugal Devan,
Well, you can keep the data in one array, but the problem in that case is, you have to take care of array bounds and correct indexes for different sections. For each section indexPath.row will start from index 0, and if your data is in single array, you have to manage the row index by your self. But still if you want to keep it, you can do like:
int sectionOneIndex = 0;
int sectionTwoIndex = 3;
NSMutableArray *sectionArray = [[NSMutableArray alloc] initWithObjects:#"email", #"Name", #"address", #"zipCode", #"country", nil];
Above two integers represents the starting position of elements of your different sections. First 3 objects from the section Array are the part of section One, and last two objects are the part of section two. Now you need to return correct row count.
For that you may write:
if(section == 0) return [sectionArray count] - (sectionTwoIndex-1); //returns 3
else if(section == 1) return [sectionArray count] - sectionTwoIndex; //returns 2
OR if your count is static you may put constant values in return.
And at the time you read from array, you will just add this index in row value, which will return the correct position of your element for the current cell.
// 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] autorelease];
}
// Configure the cell.
if(indexPath.section == 0){
cell.textLabel.text = [sectionArray objectAtIndex:indexPath.row + sectionOneIndex];
} else if (indexPath.section == 1) {
cell.textLabel.text = [sectionArray objectAtIndex:indexPath.row + sectionTwoIndex];
}
return cell;
}

What is the proper way of hard-coding sections in a UITableView?

I have a UITableView with 3 sections that are hard coded. Everything is working fine, but I am not sure if I am doing it correctly.
Define number of rows in section:
- (NSInteger)tableView:(UITableView *)tblView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows;
//Bio Section
if(section == 0){
rows = 2;
}
//Profile section
else if(section == 1){
rows = 5;
}
//Count section
else if(section == 2){
rows = 3;
}
}
return rows;
}
Here is where I build my cells:
- (UITableViewCell *)tableView:(UITableView *)tblView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tblView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.numberOfLines = 5;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:(10.0)];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
if ([self.message_source isEqualToString:#"default"]) {
if (indexPath.section == 0) {
if (indexPath.row == 0) {
cell.textLabel.text = [Utils formatMessage:[NSString stringWithFormat: #"%#", mySTUser.bio]];
cell.detailTextLabel.text = nil;
}
else if(indexPath.row == 1){
cell.textLabel.text = [NSString stringWithFormat: #"%#", mySTUser.website];
cell.detailTextLabel.text = nil;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
} //more code exists, but you get the point...
Now I define my number of sections
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tblView
{
return 3;
}
Is this the proper way of hard-coding my UITableView? Will I run into any issues when cells are reused?
You might consider using a switch-case tree with an enumerated type, to replace the if conditionals that test for various hard-coded integers. This blog post explains this option in more detail. Using switch-case with your table view delegate methods will make your code much more readable and flexible. Otherwise, your reuse code looks correct.

iPhone - didSelectRowAtIndexPath - selecting row 26 or greater mystery

My UITableView has up to 50 rows in each section, populated by a plist dictionary which contains arrays (sections) which contains arrays (row objects) which contains two strings (row title / filename and file extension).
Select row 1 - 25 (item 0-24) and everything behaves normally. But select a row greater than 26 (item 25) and the app crashes. I'm a novice at all this and I tried researching for the answer but I'm at a loss for how to research this. Can tables only have 25 rows per section?
Any ideas? Thank you!
Jon
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSMutableString *key = [categories objectAtIndex:section];
NSMutableArray *sound = [categoriesSounds objectForKey:key];
NSMutableString *soundName = [[sound objectAtIndex: row] objectAtIndex: 0];
NSMutableString *soundOfType = [[sound objectAtIndex: row] objectAtIndex: 1];
if (leftSwitch.on == YES) {
showLeft.text = soundName;
left = [[NSBundle mainBundle] pathForResource:(#"%#", soundName) ofType:(#"%#", soundOfType)];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL
fileURLWithPath:left], &soundNegZ);
AudioServicesPlaySystemSound (soundNegZ);
if (indexPath != leftOldIndexPath) {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:leftOldIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
leftOldIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
if (downSwitch.on == YES) {
showDown.text = soundName;
down = [[NSBundle mainBundle] pathForResource:(#"%#", soundName) ofType:(#"%#", soundOfType)];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL
fileURLWithPath:down], &soundNegX);
AudioServicesPlaySystemSound (soundNegX);
if (indexPath != downOldIndexPath) {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:downOldIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
downOldIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
if (rightSwitch.on == YES) {
showRight.text = soundName;
right = [[NSBundle mainBundle] pathForResource:(#"%#", soundName) ofType:(#"%#", soundOfType)];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL
fileURLWithPath:right], &soundPosX);
AudioServicesPlaySystemSound (soundPosX);
if (indexPath != rightOldIndexPath) {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:rightOldIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
rightOldIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
For "EXC_BAD_ACCESS" in the console, this is the debugger output (error trace is marked with asterisks):
0x91a6cec0 <+0000> mov 0x8(%esp),%ecx
0x91a6cec4 <+0004> mov 0x4(%esp),%eax
0x91a6cec8 <+0008> cmp $0xfffeb010,%ecx
0x91a6cece <+0014> je 0x91a6cf35 <objc_msgSend+117>
0x91a6ced0 <+0016> test %eax,%eax
0x91a6ced2 <+0018> je 0x91a6cf1a <objc_msgSend+90>
0x91a6ced4 <+0020> mov (%eax),%edx
0x91a6ced6 <+0022> push %edi
**0x91a6ced7 <+0023> mov 0x20(%edx),%edi**
0x91a6ceda <+0026> push %esi
0x91a6cedb <+0027> mov (%edi),%esi
0x91a6cedd <+0029> mov %ecx,%edx
0x91a6cedf <+0031> shr $0x2,%edx
0x91a6cee2 <+0034> and %esi,%edx
0x91a6cee4 <+0036> mov 0x8(%edi,%edx,4),%eax
0x91a6cee8 <+0040> test %eax,%eax
0x91a6ceea <+0042> je 0x91a6cef5 <objc_msgSend+53>
0x91a6ceec <+0044> cmp (%eax),%ecx
0x91a6ceee <+0046> je 0x91a6cf00 <objc_msgSend+64>
0x91a6cef0 <+0048> add $0x1,%edx
0x91a6cef3 <+0051> jmp 0x91a6cee2 <objc_msgSend+34>
0x91a6cef5 <+0053> pop %esi
0x91a6cef6 <+0054> pop %edi
0x91a6cef7 <+0055> mov 0x4(%esp),%eax
0x91a6cefb <+0059> mov (%eax),%eax
0x91a6cefd <+0061> jmp 0x91a6cf09 <objc_msgSend+73>
0x91a6ceff <+0063> nop
0x91a6cf00 <+0064> mov 0x8(%eax),%eax
0x91a6cf03 <+0067> pop %esi
0x91a6cf04 <+0068> pop %edi
0x91a6cf05 <+0069> xor %edx,%edx
0x91a6cf07 <+0071> jmp *%eax
0x91a6cf09 <+0073> sub $0x4,%esp
0x91a6cf0c <+0076> push %ecx
0x91a6cf0d <+0077> push %eax
0x91a6cf0e <+0078> call 0x91a6d33f <_class_lookupMethodAndLoadCache>
0x91a6cf13 <+0083> add $0xc,%esp
0x91a6cf16 <+0086> xor %edx,%edx
0x91a6cf18 <+0088> jmp *%eax
0x91a6cf1a <+0090> call 0x91a6cf1f <objc_msgSend+95>
0x91a6cf1f <+0095> pop %edx
0x91a6cf20 <+0096> mov 0xe79d961(%edx),%eax
0x91a6cf26 <+0102> test %eax,%eax
0x91a6cf28 <+0104> je 0x91a6cf30 <objc_msgSend+112>
0x91a6cf2a <+0106> mov %eax,0x4(%esp)
0x91a6cf2e <+0110> jmp 0x91a6ced4 <objc_msgSend+20>
0x91a6cf30 <+0112> mov $0x0,%edx
0x91a6cf35 <+0117> ret
0x91a6cf36 <+0118> nopw %cs:0x0(%eax,%eax,1)
My cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [categories objectAtIndex:section];
NSArray *nameSection = [categoriesSounds objectForKey:key];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
SectionsTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SectionsTableIdentifier] autorelease];
}
cell.textLabel.text = [[nameSection objectAtIndex:row] objectAtIndex: 0];
if (leftSwitch.on == YES){
NSUInteger leftRow = [leftOldIndexPath row];
NSUInteger leftSection = [leftOldIndexPath section];
cell.accessoryType = (row == leftRow && section == leftSection && leftOldIndexPath !=nil) ?
UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
}
if (downSwitch.on == YES){
NSUInteger downRow = [downOldIndexPath row];
NSUInteger downSection = [downOldIndexPath section];
cell.accessoryType = (row == downRow && section == downSection && downOldIndexPath !=nil) ?
UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
}
if (rightSwitch.on == YES){
NSUInteger rightRow = [rightOldIndexPath row];
NSUInteger rightSection = [rightOldIndexPath section];
cell.accessoryType = (row == rightRow && section == rightSection && rightOldIndexPath !=nil) ?
UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
}
return cell;
}
From analysing your code, I can see a few places where you can be failing.
First of all:
NSMutableString *soundName = [[sound objectAtIndex: row] objectAtIndex: 0];
NSMutableString *soundOfType = [[sound objectAtIndex: row] objectAtIndex: 1];
Do you have more than 25 elements in the sound array?
Second of all:
if (indexPath != downOldIndexPath) {
What is downOldIndexPath? Are you sure that if you pass it to this method
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:downOldIndexPath];
it is a correct index path?
When your app crashes do you see any error messages logged in the debugger console? (If it's not viewable whilst you debug your application select the Run menu -> Console menu option in XCode). You should see some log entries in here that will help to point you in the right direction.
I have 101 rows in my current project. As far as i know there isn't a limit.
As for the crash, can you give us more info? Like a stack trace? Console output?
If you were accessing more elements than the array held, you would get an out of bounds exception - not a EX_BAD_ACCESS crash.
That means you are trying to access memory you have released. There are two possibilities:
1) The item you are pulling out of the array, has been released. This is pretty unlikely as you would have had to do extra releases to get rid of something held in an array.
2) (most likely) You have released one of the arrays you are trying to get data from - or more accurately, you get the array from somewhere and then forget to retain it (since most things given to you by other methods are auto-released).
I'm having this same problem, I see you've solved it by the following:
Thanks Eddie, NSZombieEnabled pointed me in the right direction and I was able to fix the problem. Turned out my index path retain count needed to be increased by 1 in cellForRowAtIndexPath. – Jonathan Cohen Jan 25 at 18:00
Sorry I'm a bit new to iPhone programming, what does this mean exactly?
I've tried a few things and they all seem to work I'm just wondering which is the correct way!?
I have tried this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CheckMarkCellIdentifier = #"CheckMarkCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CheckMarkCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CheckMarkCellIdentifier] autorelease];
}
// need to retain to stop this crashing with rows > ~26
[indexPath retain];
NSUInteger row = [indexPath row];
NSUInteger oldRow = [lastIndexPath row];
// Print the text
cell.textLabel.text = [itemTextList objectAtIndex:row];
// Print the detail text
cell.detailTextLabel.text = [itemDetailTextList objectAtIndex:row];
cell.accessoryType = (row == oldRow && lastIndexPath != nil) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
Also (separately) I've tried both of these:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger newRow = [indexPath row];
NSUInteger oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
if (newRow != oldRow) {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath: indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath: lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
// retain indexPath to use as last index path
lastIndexPath = [indexPath retain];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
and
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger newRow = [indexPath row];
NSUInteger oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
if (newRow != oldRow) {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath: indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath: lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
// get a copy to use as last index path
lastIndexPath = [indexPath copy];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Now I'm wavering towards the last [indexPath copy], is this the correct way to do it from a memory management point of view? Or does it not really matter whether I retain or copy it?
Thanks,
Matt.