I want to stop all the rows being deleted from my table view by user so at least one row is always present.
Im still geting to grips with programming and objective c.
Heres what I tried:
if (indexPath.section != 0 | editingStyle == UITableViewCellEditingStyleDelete) {
[self.managedObjectContext deleteObject:[self.circuits objectAtIndex:indexPath.row]];
[self.appDelegate saveContext];
[self.circuits removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
then
if (indexPath.section > 1 | editingStyle == UITableViewCellEditingStyleDelete) {
[self.managedObjectContext deleteObject:[self.circuits objectAtIndex:indexPath.row]];
[self.appDelegate saveContext];
[self.circuits removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
That had no effect in that I can still delete the first row. So then I tried
- (BOOL)tableView:(UITableView *)commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0)
return NO;
return YES;
}
Still cant prevent the first row from being deleted
You need to implement the UITableViewDataSource method tableView:canEditRowAtIndexPath: and return NO for the indexPath.row 0.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath.row > 0;
}
Try moving your code into
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
Try this code :-
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0)
return NO;
else
return YES;
}
It will surely help you
Related
I need to add the "swipe to delete" feature on my UITableView, I tried with the following code:
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[indexProdotti removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else {
NSLog(#"Unhandled editing style! %ld", (long)editingStyle);
}
}
The problem is that there is only a limited space I have to swipe in order to show the delete button, the rest of the cell if swiped gives no result.. Am I missing something in my implementation?
My UITableView has one section, and if all cells are visible there will be a total of 6.
There is only one cell that I would like to be able to show and hide.
Here's an overview:
cell 0 - always shown
cell 1 - always shown
cell 2- always shown
cell 3 - always shown
cell 4 - initially hidden / will show or hide if cell 3 is tapped
cell 5 - always shown
Here's a sample of what I have tried for animating/showing the cell through didSelectRowAtIndexPath. Not sure if I am on the right track, but if someone could take a look and help me see where I have messed up I would greatly appreciate it!
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.row == 3)
{
if (self.indexPathSelected != indexPath)
{
[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:self.indexPathSelected.row+1 inSection:self.indexPathSelected.section]].hidden = YES;
[tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationTop];
[tableView beginUpdates];
[[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section]] performSelector:#selector(setHidden:) withObject:NO afterDelay:0.25];
self.indexPathSelected = indexPath;
[tableView endUpdates];
return;
}
}
}
So when I tap on cell 3, it just makes the last cell flicker.
By considering, there will be of total 6 rows in tableview and only one section, for this better u make a mutable array to hold all the objects for ur tableview then use insertRowsAtIndexPaths: withRowAnimation: and deleteRowsAtIndexPaths: withRowAnimation: instead of using selector following code gives the example how to hide and show the tableview cell
mutArray = [[NSMutableArray alloc]initWithObjects:#"cell 1",#"cell 2",#"cell 3",#"cell 4",#"cell 6", nil]; //initially ur array contains only 5 objects notice that "cell 5" is not there this will be hidden
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [mutArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.aTableView dequeueReusableCellWithIdentifier:#"cell"];
if(mutArray.count != 6) //initially only 5 rows are present
{
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.textLabel.text = [mutArray objectAtIndex:indexPath.row];
cell.textLabel.backgroundColor = [UIColor clearColor];
return cell;
}
else //for 5th row it must be a custom cell
{
return [mutArray objectAtIndex:indexPath.row];//becz u are already initilised ur custom cell just return it
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if(indexPath.row == 3)
{
int totalRows = [tableView numberOfRowsInSection:indexPath.section];
[tableView beginUpdates];
if(totalRows == 5)
{
//initilise ur custom cell and add it to datasource array
CustomCell *customCell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"customCell"];
customCell.textLabel.text = #"cell 5";
[mutArray insertObject:customCell atIndex:4];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:indexPath.row + 1 inSection:indexPath.section]] withRowAnimation:UITableViewRowAnimationFade];
}
else
{
[mutArray removeObjectAtIndex:5];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:indexPath.row + 1 inSection:indexPath.section]] withRowAnimation:UITableViewRowAnimationFade];
}
[tableView endUpdates];
}
}
if all ur cells are custom then dont need to comepare in -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method
Hope this helps u :)
Want to delete a row when you swipe with your finger on the cell.
I got this:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Delete");
}
After running the Delete button appears but when I press on it nothing happens. What do I need to insert in to the brackets?
And my .m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *str = cell.textLabel.text;
NSLog(#"U selected %#", str);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.dataSourceArray removeObjectAtIndex:indexPath.row];//or something similar to this based on your data source array structure
//remove the corresponding object from your data source array before this or else you will get a crash
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.array = #[#"test",#"test"];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:nil action:#selector(updateArray) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
}
Try this,
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.array removeObjectAtIndex:indexPath.row];//or something similar to this based on your data source array structure
//remove the corresponding object from your data source array before this or else you will get a crash
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
I have a table with 7 section and in each section 2 rows, I don't know why my delete button doesn't work!! and not appear in cells
would you please help me!
Thanks in advance!
day.m
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
arry = [[NSMutableArray alloc] init];
[arry addObject:#"test"];
[arry addObject:#"hey"];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addNewItem)];
self.navigationItem.rightBarButtonItem = rightButton;
}
-(void)addNewItem
{
[arry addObject:#"New Day"];
[self.tableView reloadData];
}
// ... standard methods to override
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 7;
//_week.days.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [arry count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
cell.textLabel.text = [arry objectAtIndex:indexPath.row];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(section == 0)
{
return #"Monday";
}
else if(section == 1)
{
return #"Tuesday";
}
else if(section == 2)
{
return #"Wednesday";
}
else if(section == 3)
{
return #"Thuesday";
}
else if(section == 4)
{
return #"Friday";
}
else if(section == 5)
{
return #"Saturday";
}
else
{
return #"Sunday";
}
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// [self.monthTitle removeObjectAtIndex:indexPath.row];
[arry removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
else if (editingStyle==UITableViewCellEditingStyleInsert)
{
}
}
Edit1: after removing multiple selection from storyboard delete button appears but when I click on delete button it's terminated
You didn't begin your table updates.
When you use the method "deleteRowsAtIndexPath", you must insert it between this methods:
// Begin update
[tableView beginUpdates];
// Perform update
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
// End update
[tableView endUpdates]
From your screenshot, it looks like you've set allowsMultipleSelectionDuringEditing to YES (perhaps in your nib file, as I can't see that in the code). When that's the case, tableView:commitEditingStyle:forRowAtIndexPath: will never be called, because the checkmarks only indicate the user's selection, not that these rows should be deleted.
You need a delete button of your own that is activated when you enter editing mode, similar to how you see it in the Mail app.
you should first remove row from the datasource like this,
[self.table_favpropertylist_array removeObjectAtIndex:indexPathRow];
[tbl_FavDetails beginUpdates];
UITableViewCell *cell=[tbl_FavDetails cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPathRow inSection:0]];
NSIndexPath *indexPath = [tbl_FavDetails indexPathForCell:cell];
[tbl_FavDetails deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tbl_FavDetails endUpdates];
where self.table_favpropertylist_array is datasource ,tbl_FavDetails is tableview and indexPathRow is index at which row delete button is clicked,
Thanks.
I am having a big issue trying to delete from an UITableView.
Just for note, I have the same code running fine on another view and thats why it's making me crazy.
The only difference is that on the other view, my array is in a property. But I tried changing my tmpArray to a property and nothing changed. Here's the code and the error after:
-(void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tmpArray removeObjectAtIndex:indexPath.row];
[tbvPlaylist deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Error:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1046
Let me now if you need more info.
Is tmpArray the same ivar that is providing the count of rows e.g.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return tmpArray.count;
}
Also at the moment you call
[tbvPlaylist deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
tableView:numberOfRowsInSection: should return the
numberOfRowsBeforeDelete - numberOfRowsBeingDeleted