UITableView is crashing on NSArray index 1 beyond bounds - ios

My table keeps crashing. "Index 1 beyond bounds".
I return the an array count for the number of rows in the section, but as soon as I scroll to the second row (index 1) the app crashes.
I have two sections. One with a set number of rows and the second section is a dynamically created based upon the number of items in the array.
Any thoughts?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2; //two seperate areas
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return 16;
} else {
NSLog(#"Section: %ld, NumberOfRows: %lu", (long)section, (unsigned long)[self.arrImages count]);
return [self.arrImages count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
switch (section) {
case 0:
cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
break;
case 1:
cell = [tableView dequeueReusableCellWithIdentifier:#"cellPhoto"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cellPhoto"];
}
NSLog(#"Row: %lu\n%#", (unsigned long)row, [[self.arrImages objectAtIndex:row] objectForKey:#"imageThumbnailURL"]);
cell.imageView.image = [self imageFromURL:[[self.arrImages objectAtIndex:row] objectForKey:#"imageThumbnailURL"] fromCache:YES];
NSLog(#"completed");
break;
}
return cell;
}
#pragma mark UITableViewDelegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger section = [indexPath section];
[self doneData];
switch (section) {
case 1:
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self performSegueWithIdentifier:#"segue_showphoto" sender:self];
break;
}
}
Here is my crash log
2015-02-12 19:32:51.817 Tops[17236:5681531] Row: 0
https://somethinghere.jpeg
2015-02-12 19:32:51.825 Tops[17236:5681531] completed
2015-02-12 19:32:51.855 Tops[17236:5681531] Row: 1
https://somthinghere.jpeg
2015-02-12 19:32:51.856 Tops[17236:5681531] completed
2015-02-12 19:32:51.862 Tops[17236:5681531] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

The implementation I was missing was:
-(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
return 0;
}

Related

Issue with displaying banner ads Objective-C

I have an issue while displaying BannerAds for 1st and every 5th row. While displaying data, first row is replaced with banner ads and every 5th row data is replaced with banner ads...How to overcome this. Following is what i have tried.TIA
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger n;
n= [array count];
return n;
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 5 == 0) {
//configure ad cell
for(UIView* view in cell.contentView.subviews) {
if([view isKindOfClass:[GADBannerView class]]) {
[view removeFromSuperview];
}
}
else
{
Title.text=[NSString stringWithFormat:#"%# ",[dict objectForKey:#"Name"]];
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 5 == 0)
return 60;
else
return 153;
}
You need to increase the number of cells you return in numberOfRowsInSection and account for the added rows in cellForRowAt
The number of advertisements will be 1 + n/5 (The first row and then every 5th row), so the number of cells in your table will be n + n/5 + 1
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger n;
n= [array count];
return n/5 + n + 1;
}
Now, some of the cells you need to return from cellForRowAt will be ads and you will need to account for this when accessing your data array. The index you need is the row number - the number of advertisement rows that have come before it. This is index/5 + 1 (The first row and every 5 rows).
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 5 == 0) {
AdCell *cell = (AdCell *)[tableView dequeueReusableCellWithIdentifier:"Ad" forIndexPath: indexPath];
...
NSLog(#"Showing an ad at row %ld",indexPath.row);
return cell;
else
{
NSInteger index = indexPath.row - indexPath.row/5 - 1;
NSDictionary *dict = myArray[index];
NormalCell *cell = (NormalCell *)[tableView dequeueReusableCellWithIdentifier:"Normal" forIndexPath: indexPath];
cell.title.text=[NSString stringWithFormat:#"%# ",dict["Name"]];
NSLog(#"Showing a normal row at row %ld (data from element %ld of array)",indexPath.row,index);
return cell;
}
}

Nested UITableView in a UITableView Causes NsRangeException with Index Out of Bound in iOS

I have an iOS 7/8 application. In a view I have a static UITableView with given number of cells - 17 in my case.
One of the cells contains another UITableView with dynamic cells. In the case described they are 20.
Because of the difference in the number of cells (+3) I get
NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 17 beyond bounds [0 .. 16]
exception when I set the 18th cell in the dynamic view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == _dynamicTableView) {
NSLog(#"%lu", (unsigned long)[[_filter types] count]);
return [[_filter types] count];
} else {
return 17;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == _dynamicTableView) {
static NSString *cellIdentifier = #"type";
TypeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[TypeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier];
}
NSArray *types = [_filter types];
Type *type = [types objectAtIndex:[indexPath row]];
[cell.nameLabel setText:[type name]];
return cell;
} else {
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
}
When I go to the Storyboard and increase the number of static cells to something like 30 everything works fine. tableView:numberOfRowsInSection... method removes the unused cells - only 17 static and 20 dynamic cells are shown.
I am aware that the source of my problem is having two UITableView-s in one controller and the large amount of 'if'-s.
Try to check with tags, you can give different tags to each table and return number of cells according to that.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView.tag == 1) // Tag for _dynamicTableView
{
return [[_filter types] count];
}
else {
return 17;
}
}

Calling uitableview while clicking uitextfield-Data not displaying -iOS

I want to display data in uitableview when the particular uitextfield is tapped. I am not getting the data in taleview. Please check the below and help me.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier ];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[cell.textLabel setFont:[UIFont fontWithName:#"Bold" size:20]];
if (ethnicityField.tag == 1)
{
cell.textLabel.text = [data objectAtIndex:indexPath.row];
}
if (languageField.tag == 2)
{
cell.textLabel.text = [langData objectAtIndex:indexPath.row];
}
Here, when I click on the first textfield it shows the empty table and crashes.
It's not taking the exact tag value. Please help.
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section{
int row = 0;
if (ethnicityField.tag == 1)
{
row = [data count];
}
if (languageField.tag == 2)
{
row = [langData count];
}
return row;
}
Crash report:
Actually I have 2 arrays, one with 5 values and another with 11 values, the problem is both textfield takes first array and if I select the 5th object in second textfield it shows the following error.
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 9 beyond bounds [0 .. 4]'
I believe ethnicityField and languageField always have the same tag so numberOfRowsInSection always returns [data count];
What you could do is checking whether a textfield is active when you display your table.
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section{
int row = 0;
if ([ethnicityField isFirstResponder])
{
row = [data count];
}
else if ([languageField isFirstResponder])
{
row = [langData count];
}
return row;
}

One ViewController with 2 TableViews - App crashes

I have a one View controller managing 2 tableviews. I use a flag to track which table is selected. In each of the delegate functions I just check the flag and use the right table.
Everything works great except that when i load the second table which has lesser items than the first one, crashes when I scroll the table , for the following error.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 2 in section at index 0'
* First throw call stack:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Drawing Row = %d Total num Of items = %d", indexPath.row, [[self.fetchedResultsControllerComments fetchedObjects] count]);
Prints this:
Drawing Row = 2 Total num Of items = 0
If the number of items in this table is correct, then why is this function getting called in the first place?
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(currentSelectionTableType1)
{
// Draw first kind of cell.
PlainImageCell *cell1 = [tableView dequeueReusableCellWithIdentifier:#"ImageCell"];
if(cell1 == nil)
cell1 =[[PlainImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"ImageCell"];
[self configureCell1:cell1 atIndexPath:indexPath];
return cell1;
}
// else Draw the second kind of cell
PlainTextCell *cell2 = [tableView dequeueReusableCellWithIdentifier:#"TextCell"];
if(cell2 == nil)
cell2 =[[PlainTextCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"TextCell"];
[self configureCell2:cell2 atIndexPath:indexPath];
return cell2;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if(currentSelectionTableType1)
return [[self.fetchedResultsControllerDataSource1 sections] count];
return [[self.fetchedResultsControllerDataSource2 sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo;
if(currentSelectionTableType1)
{
sectionInfo = [self.fetchedResultsControllerDataSource1 sections][section];
}
else
{
sectionInfo = [self.fetchedResultsControllerDatasource2 sections][section];
}
return [sectionInfo numberOfObjects];
}
Thx
EDIT - based on the code you added:
You need to define one cell before your conditional and then configure that cell based on the conditional and then return the cell after the conditional. If you need both an ImageView and a TextCell, you can configure those objects in the conditional code.
Why not just use one TableView with two datasources and switch out the datasources as needed?
Something like this:
#property(nonatomic, strong) NSArray *tableViewDataSource1;
#property(nonatomic, strong) NSArray * tableViewDataSource2;
#property(nonatomic) BOOL usingDataSource2;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.usingDataSource2) {
return [self.tableViewDataSource2 count];
}
return [self. tableViewDataSource1 count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Create the cell before conditional
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"reuseIdentifier" forIndexPath:indexPath];
// Conditionally configure the cell
if (self.usingDataSource2) {
// Configure Cell using self.tableViewDataSource2 data
} else {
// Configure Cell using self.tableViewDataSource1 data
}
// Return the configured cell after the conditional
return cell;
}

Strange behavior of UITableView when editing

I have a editable UITableView (with adding and deleting elements) in my application.
It working strange.
While I have only one or two lines in it, everything is working perfect.
But if I add more items, I have an exception '*** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
I was unable to put breakpoints and handle it.
Maybe, somebody can help me?
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int plusRow = 0;
if ([[self tableView] isEditing]) plusRow = 1;
return [typeList count] + plusRow;
}
- (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];
}
if ([indexPath row] > ([typeList count]-1)) {
NSString * appendCellDescription = #"";
if ([[self tableView] isEditing]) appendCellDescription = #"Add";
[[cell textLabel] setText:appendCellDescription];
} else {
NSLog(#"Accessing array: %d", [indexPath row]);
[[cell textLabel] setText:[[typeList getObject:[indexPath row]] description]];
}
return cell;
}
#pragma mark - Editing table view
- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"Row: %d, count: %d", [indexPath row], [typeList count]);
if (indexPath.row > [typeList count]-1) {
return UITableViewCellEditingStyleInsert;
} else {
return UITableViewCellEditingStyleDelete;
}
}
- (IBAction)btnModifyClick:(id)sender{
if ([[self tableView] isEditing]) {
[[self tableView] setEditing:FALSE animated:YES];
[[self tableView] reloadData];
} else {
[[self tableView] setEditing:TRUE animated:YES];
[[self tableView] reloadData];
}
}
Generally This Error describe, When mistake in Array Index such like you array have 3 item and you tring to get/abstract 4th item from Array, at that time this type of Error generate.
Best way to find error use BreakPint. and Debug your project line by line. and find where your app. crush ?? i am sure that it cruse Around any array.
EDIT:
I thinks mistake in array name typeList check it in cellForRowAtIndexPath method with BreakPoint.
numberOfRowsInSectionis returning higher number of items count than the one fetched in cellForRowAtIndexPath datasource method, try debugging the returned value:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int plusRow = 0;
if ([[self tableView] isEditing]) plusRow = 1;
NSLog(#"%i",[typeList count] + plusRow);
return [typeList count] + plusRow;
}
I have found a way, to solve my problem.
I just changed "Sections" to 0 in XCode properties in storyboard TableView.
And now working ok.
Thanks to everyone to response!

Resources