-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"Cell";
MagazineListCell* cell=(MagazineListCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil)
{
NSArray *arr=[[NSBundle mainBundle]loadNibNamed:#"MagazineListCell" owner:nil options:nil];
cell=(MagazineListCell *)[arr objectAtIndex:0];
[cell setDelegate:self];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
NSMutableArray *arr=[[NSMutableArray alloc]init];
NSInteger startIndex;
NSInteger endIndex;
if(isLandscape)
{
startIndex=indexPath.row*3;
if (startIndex+3>[self.arrMagazine count ])
{
endIndex=[self.arrMagazine count];
}
else
{
endIndex=startIndex+3;
}
}
else
{
startIndex=indexPath.row*2;
if (startIndex+2>[self.arrMagazine count])
{
endIndex=[self.arrMagazine count];
}
else
{
endIndex=startIndex+2;
}
}
for (int x=startIndex; x<endIndex; x++)
{
[arr addObject:[self.arrMagazine objectAtIndex:x]];
}
[cell setSelectedIndex:btnSegment.selectedSegmentIndex];
[cell contentForTableViewCell:arr setUIMode:isLandscape] ;
arr=nil;
return cell;
}
Check that your reuse identifier is being set as you may be creating the cell every time.
The main problem is probably going to be the array you're creating every time, looping around to populate and then passing on to the cell. You should try to do all of that setup before you need it.
Related
I'm trying to sort my table by date header and have been doing this for days now but my tableview doesn't seem to return a cell. But if I remove the if(zrrot < [mEvents count] ) condition it will return a cell. It's weird.
I cannot put indexPath.row in here [cell setEvent:[mEvents objectAtIndex: ]]; because it will not sort the data according to its the header.
(The app is a voip app)
Here's my code:
NSUInteger zzrot = 0;
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RecentsCell *cell = (RecentsCell*)[_tableView dequeueReusableCellWithIdentifier: #"RecentsCell"];
if (cell == nil) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"RecentsCell" owner:self options:nil] lastObject];
}
if([[myArray objectAtIndex:indexPath.section] isEqual: finalArray[indexPath.section][indexPath.row]])
{
if(zrrot < [mEvents count] ){
#synchronized(mEvents){
[cell setEvent:[mEvents objectAtIndex: zzrot]];
zrrot++;
}
}
return cell;
}
else{
NSLog(#"Do nothing");
//do nothing
return cell;
}
}
Here's the setEvent:
-(void)setEvent: (NgnHistoryEvent*)event{
labelType.text = event.remoteParty;
labelDisplayName.text = event.remotePartyDisplayName;
labelDate.text = [[NgnDateTimeUtils chatDate] stringFromDate:
[NSDate dateWithTimeIntervalSince1970: event.start]];
}
}
When my app's user signs up for an account, the tableView starts out empty (as no data has been added by the user). How can I stop the app from crashing when the soon-to-be populated array is empty? So far, I've tried displaying a view when the table/array is empty, but the crash still occurs...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.storageData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *DoctorsTableIdentifier = #"StorageItemTableViewCell";
StorageItemTableViewCell *cell = (StorageItemTableViewCell *)[tableView dequeueReusableCellWithIdentifier:DoctorsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StorageItemTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (self.storageData > 0) {
noitemsView.hidden = YES;
NSDictionary *tmp = [self.storageData objectForKey:[NSString stringWithFormat:#"%d",(long)indexPath.row]];
[[cell itemName] setText:(NSString *)[tmp objectForKey:#"title"]];
NSString *title = [tmp objectForKey:#"title"];
[[cell itemName] setText:title];
NSDictionary *node = [self.descripData objectAtIndex:indexPath.row];
[[cell itemDescrip] setText:[node objectForKey:#"body"]];
NSLog(#"%#", self.descripData);
NSString *secondLink = [[self.descripData objectAtIndex:indexPath.row] objectForKey:#"photo"];
[cell.itemPhoto sd_setImageWithURL:[NSURL URLWithString:secondLink]];
NSLog(#"%#",secondLink);
}
else {
noitemsView.hidden = NO;
}
return cell;
}
You need to update your numberOfRows Delegate method
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([self.storageData count] > 0 && self.descripData.count>0)
{
return [self.storageData count];
}
else
return 1;
}
Also modify the code as below
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
----------
if (self.storageData.count > 0 && self.descripData.count>0) {
------------//Instead of self.storageData>0
}
----------
}
It fixes the crash issue if storageData is empty..!
Try the following.
self.tableView.dataSource = self.storageData ? self : nil;
This is not really correct, but since your question is specifically about making the app not crash, you could do this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.storageData)
return [self.storageData count];
else
return 1;
}
This means that if the array is not empty, display the number of elements in the array. Else, display just 1 (or whatever default number you want).
Also, in cellForRowAtIndexPath, you need to make the same check:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *DoctorsTableIdentifier = #"StorageItemTableViewCell";
StorageItemTableViewCell *cell = (StorageItemTableViewCell *)[tableView dequeueReusableCellWithIdentifier:DoctorsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StorageItemTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (self.storageData) // <-- check for nil values first
{ if (self.storageData > 0) {
//more code
}
Again, not good or correct, but it makes the app not crash, which is what you asked about.
Here is a problem:
if (self.storageData > 0) {
noitemsView.hidden = YES;
....
You are comparing self.storageData > 0 instead of [self.storageData count] > 0, so the if is always evaluating to true, and it is always trying to create a cell with data that is not available.
write code in view did load
self.storageData = [[NSMutableArray alloc] init];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//If "numberOfRowsInSection" return '0' or nil, "cellForRowAtIndexPath" should not be called.
//Are you sure the "self.storageData.count" is empty?
if (_storageData == nil)
{
return 0;
}
else
{
return _storageData.count;
}
}
You need to check array count in number of row in section method:
1.
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(!myArray.count)
return 0;
return [myArray.count];
}
Could any one help me? Am working on expanding cell for the past one week Finally i can able to add sub menu in it. I designed two custom cells and using plist i added menu and sub menu to that. It is working well i added menu and sub menu. Now my problem is i want to add image and button to row 1,2,4,6 only using indexpath.row i assigned but this code assigning image and button to all rows But i only want to add to row 1,2,4,6 only ho i can do this pls some one help me???
interface MyHomeView ()
{
NSMutableArray *LeftPaneList;
NSArray *datalist;
}
#property (assign)BOOL isOpen;
#property (nonatomic,retain)NSIndexPath *selectIndex;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"LeftPaneMenuList" ofType:#"plist"];
LeftPaneList = [[NSMutableArray alloc] initWithContentsOfFile:path];
self.isOpen=NO;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [LeftPaneList count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.isOpen) {
if (self.selectIndex.section == section) {
return [[[LeftPaneList objectAtIndex:section] objectForKey:#"SubMenu"] count]+1;;
}
}
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.isOpen&&self.selectIndex.section == indexPath.section&&indexPath.row!=0) {
static NSString *CellIdentifier = #"MyHomeViewCell2";
MyHomeViewCell2 *cell = (MyHomeViewCell2*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil] objectAtIndex:0];
}
NSArray *list = [[LeftPaneList objectAtIndex:self.selectIndex.section] objectForKey:#"SubMenu"];
cell.name.text = [list objectAtIndex:indexPath.row-1];
return cell;
}
else
{
static NSString *CellIdentifier = #"MyHomeViewCell";
MyHomeViewCell *cell = (MyHomeViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil] objectAtIndex:0];
}
cell.tag=indexPath.row;
NSString *name = [[LeftPaneList objectAtIndex:indexPath.section] objectForKey:#"MenuName"];
cell.MyHomeMenuLabel.text = name;
return cell;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
if ([indexPath isEqual:self.selectIndex]) {
self.isOpen = NO;
[self didSelectCellRowFirstDo:NO nextDo:NO];
self.selectIndex = nil;
}else
{
if (!self.selectIndex) {
self.selectIndex = indexPath;
[self didSelectCellRowFirstDo:YES nextDo:NO];
}else
{
[self didSelectCellRowFirstDo:NO nextDo:YES];
}
}
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)didSelectCellRowFirstDo:(BOOL)firstDoInsert nextDo:(BOOL)nextDoInsert
{
self.isOpen = firstDoInsert;
[self.MyHomeTableView beginUpdates];
int section = self.selectIndex.section;
int contentCount = [[[LeftPaneList objectAtIndex:section] objectForKey:#"SubMenu"] count];
NSMutableArray* rowToInsert = [[NSMutableArray alloc] init];
for (NSUInteger i = 1; i < contentCount + 1; i++) {
NSIndexPath* indexPathToInsert = [NSIndexPath indexPathForRow:i inSection:section];
[rowToInsert addObject:indexPathToInsert];
}
if (firstDoInsert)
{ [self.MyHomeTableView insertRowsAtIndexPaths:rowToInsert withRowAnimation:UITableViewRowAnimationTop];
}
else
{
[self.MyHomeTableView deleteRowsAtIndexPaths:rowToInsert withRowAnimation:UITableViewRowAnimationTop];
}
[self.MyHomeTableView endUpdates];
if (nextDoInsert) {
self.isOpen = YES;
self.selectIndex = [self.MyHomeTableView indexPathForSelectedRow];
[self didSelectCellRowFirstDo:YES nextDo:NO];
}
if (self.isOpen) [self.MyHomeTableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionTop animated:YES];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 52;
}
This is the original o/p!
But i want o/p like this
some one help me??
you need to specify IndexPath.section First then you can check with IndexPath.row like Bellow Example:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if(indexPath.section==0)
{
if(indexPath.row==0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else if(indexPath.row==2)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else if(indexPath.row==2)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else if(indexPath.row==4)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else if(indexPath.row==6)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
}
}
}
Th easy way to do this, is to set up 2 different dynamic prototype cells in the storyboard, each with its own identifier. In cellForRowAtIndexPath: dequeue the correct type of cell based on the indexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if (indexPath.row = 1 || indexPath.row = 2 || indexPath.row = 4 || indexPath.row = 6){
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}else{
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
}
As you are using dequeueReusableCellWithIdentifier: method, it will just give cell at index path 2, 4, 6 etc to some other cell in tableView. Instead use array to store your cell and then retrieve it from array. And then you can use indexpath.row
Edited code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil)
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (isFiltered) {
int rowCount=indexPath.row;
Aves *filtrada=[filteredTableData objectAtIndex:rowCount];
cell.textLabel.text=filtrada.name;
NSLog(#"mostrando: ");
}else {
int rowCounter=indexPath.row;
Aves *author=[theauthors objectAtIndex:rowCounter];
cell.textLabel.text=author.name;
}
NSLog(#"mostrando: ");
return cell;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = true;
int i;
[filteredTableData removeAllObjects];
for(i=0;[theauthors count]>i;i++)
{
Aves *name=[theauthors objectAtIndex:i];
//NSLog(name.name);
NSRange nameRange = [[name.name lowercaseString] rangeOfString:[text lowercaseString]];
if(nameRange.length>0)
{
[filteredTableData addObject:name];
NSLog(name.name);
}
}
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
}
Edit: After working on it a while I solved some problems.Just updated my code, the problem is the repaint of the tableView, every thing else go ok. Check it and give any ideas you have plz ^^
Thx again for your time.
I assume you're using prototype cells? I just had a similar problem in one of my projects.
When search results are displayed and tableView:cellForRowAtIndexPath: is called, the table view passed in the the table belonging to the search results controller, not your main table view. Problem with that is, the search results table view doesn't know anything about your table's prototype cells, so dequeueReusableCellWithIdentifier: returns nil. But just alloc/init'ing a UITableCellView won't give you one of your prototype cells, so whatever UI you laid out in your storyboard isn't there.
The fix is easy: in tableView:cellForRowAtIndexPath:, don't call dequeueReusableCellWithIdentifier: on the tableview passed in; just call it on your main table view. So basically, just change this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil)
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
to this:
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
There's no need for the nil check; Apple's Storyboards Release Notes says:
The dequeueReusableCellWithIdentifier: method is guaranteed to return
a cell (provided that you have defined a cell with the given
identifier). Thus there is no need to use the “check the return value
of the method” pattern as was the case in the previous typical
implementation of tableView:cellForRowAtIndexPath:.
does your app hits this code if(nameRange.location ==0) ?
Change the code piece of
else
{
isFiltered = true;
int i=0;
[filteredTableData removeAllObjects];
filteredTableData = [[NSMutableArray alloc] init];
//for (Aves* name in theauthors)
for(i=0;[theauthors count]>i;i++)
{
Aves *name=[theauthors objectAtIndex:i];
NSRange nameRange = [name.foodName rangeOfString:text ];
if(nameRange.location ==0)
{
[filteredTableData addObject:name];
}
[self.tableView reloadData];
}
}
to
else
{
isFiltered = true;
int i=0;
[filteredTableData removeAllObjects];
//filteredTableData = [[NSMutableArray alloc] init]; not needed
//for (Aves* name in theauthors)
for(i=0;[theauthors count]>i;i++)
{
Aves *name=[theauthors objectAtIndex:i];
NSRange nameRange = [name.foodName rangeOfString:text ];
if(nameRange.location != NSNotFound)
{
[filteredTableData addObject:name];
}
}
[self.tableView reloadData];
}
use this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//If the requesting table view is the search display controller's table view, return the count of the filtered list, otherwise return the count of the main list.
if (isFiltered)
{
return [filteredTableData count];
}
else
{
return [theauthors count];
}
}
Replace method:
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = true;
int i=0;
[filteredTableData removeAllObjects];
filteredTableData = [[NSMutableArray alloc] init];
//for (Aves* name in theauthors)
for(i=0;[theauthors count]>i;i++)
{
Aves *name=[theauthors objectAtIndex:i];
NSRange nameRange = [[name.foodName lowercaseString] rangeOfString:[text lowercaseString]];
if(nameRange.length>0)
{
[filteredTableData addObject:name];
[self.tableView reloadData];
}
}
}
}
finally fixed it. Here is my working code, thx you all =)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
if (isFiltered==TRUE) {
int rowCount=indexPath.row;
//for (rowCount=0; rowCount<[filteredTableData count]; rowCount++) {
Aves *filtrada=[filteredTableData objectAtIndex:rowCount];
cell.textLabel.text=filtrada.name;
//}
}else if(isFiltered==FALSE)
{
int rowCounter=indexPath.row;
Aves *author=[theauthors objectAtIndex:rowCounter];
cell.textLabel.text=author.name;
}
return cell;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text {
[filteredTableData removeAllObjects];
filteredTableData=[[NSMutableArray alloc]init ];
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = TRUE;
int i;
for(i=0;[theauthors count]>i;i++)
{
Aves * filtrado=[[Aves alloc]init];
filtrado=[theauthors objectAtIndex:i];
//NSLog(filtrado.name);
NSRange nameRange = [[filtrado.name lowercaseString] rangeOfString:[text lowercaseString]];
if(nameRange.length>0)
{
[filteredTableData addObject:filtrado];
}
}
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil
waitUntilDone:NO];
}
}
You probably want to replace
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
with in your cellForRowAtIndexPath
UITableViewCell *cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
The reason because you're not getting use of the dequeued cell anyway.
I have problem with deleting rows from table. I have a class for cell of table and a sql database. Then I loading table from database and do smth with it. Now when i try to delete rows by index paths, I have an exception.
- (void)viewDidLoad
{
[super viewDidLoad];
databasecontroller=((SexyGirlsWeatherAppDelegate *)[[UIApplication sharedApplication] delegate]).databasecontroller;
self.favorites=[databasecontroller select:#"SELECT Name, id FROM Favorites"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = (CustomCell *)[favoritesTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
[favoritesTableView setBackgroundColor:[UIColor clearColor]];
cell.name.text = [[favorites objectAtIndex:indexPath.row] objectForKey:#"Name"];
cell.currenttemp.text=#"+45 C";
cell.currentweather.image=[UIImage imageNamed:#"sunny"];
//[cell.selectcell setBackgroundImage:[UIImage imageNamed:#"selectfalse"] forState:UIControlStateNormal];
cell.razdelitel.image=[UIImage imageNamed:#"delenie"];
if(editModeOn==YES) [cell EditModeON];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(editModeOn==YES)
{
int existcount=0;
for(int z=0; z<[selectrowsarray count];z++)
{
if([selectrowsarray objectAtIndex:z]==indexPath) // check for exist of item
{
[selectrowsarray removeObjectAtIndex:z];
existcount++;
}
}
if(existcount==0)
{
[selectrowsarray addObject:indexPath];
}
}
}
-(IBAction) deleteSelectedTownsFromFavorites:(id)sender // here i try to delete cells
{
// [favoritesTableView beginUpdates];
// [databasecontroller exec:[NSString stringWithFormat:#" DELETE FROM Favorites WHERE Id=%d", 3]];
// [favoritesTableView reloadData];
// [databasecontroller exec:#"UPDATE Favorites"];
// for(int t=0; t<[selectrowsarray count];t++)
// {
//
[favorites removeLastObject];
[favoritesTableView deleteRowsAtIndexPaths:selectrowsarray withRowAnimation:UITableViewRowAnimationMiddle];
// }
optionsview.hidden=true;
// [favoritesTableView endUpdates];
}
- (NSInteger)tableView:(UITableView *)favoritesTableView numberOfRowsInSection:(NSInteger)section
{
//return [favorites count];
return [favorites count];
}
How I could to synhronize 2 arrays (from database and from selectcelladdresses) for correcting deleting rows?
You also have to delete the cell from the datasource.