Swipe to delete - objective-c

I Have a tableview and a cell in it :D with disclosure accessory selected. I created all ui elements with storyboard.
(didn't put a view in content of the cell)
I'm using SWTableViewCell to implement just swipe-to-delete, but everything seems work fine except when i put a breakpoint on to a method
#pragma mark -SWTableViewDelegate-
-(void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index
{
NSIndexPath *path=[self.table indexPathForCell:cell];
[anArray removeObjectAtIndex:path.row];
[self.table deleteRowsAtIndexPaths:#[path] withRowAnimation:UITableViewRowAnimationRight];
}
and this will help you to understand what i simply done here
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
SWTableViewCell *cell=(SWTableViewCell*)[tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if (!cell)
{
NSMutableArray *rightUtilityButtons = [NSMutableArray new];
[rightUtilityButtons sw_addUtilityButtonWithColor:[UIColor colorWithRed:1.0f
green:0.231f
blue:0.188
alpha:1.0f]
title:#"Delete"];
cell = [[SWTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell" containingTableView:_table leftUtilityButtons:nil rightUtilityButtons:rightUtilityButtons];
}
NSMutableDictionary *deDict=[[NSMutableDictionary alloc]initWithDictionary:[anArray objectAtIndex:indexPath.row]];
cell.textLabel.text= [deDict objectForKey:#"Name"];
return cell;
}
Yet, I don't get any error, because when i try to swipe on simulator, it simply does not work..

No need to use SWTableViewCell just Override following built-in methods of UITableView delegate for support conditional editing & swipe to delete
for conditional editing -- Optional --
//Override this method only if you are going to be returning NO for some items.
//By default, all items are editable.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return YES if you want the specified item to be editable.
return YES;
}
for swipe to delete
// Override to support editing the table view.
// for swipe to delete
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
}
}

Related

UITableViewCell on left swipe doesn't trigger editActionsForRowAtIndexPath

I have a scrollview which contains different subviews, one of which is tableview. I also have a UITapGestureRecognizer and UISwipeGestureRecognizer initialized on the scroll view. The tableview uses a nib to initialize its cell.
What I would like to do is that, when I swipe the cell to the left, I want a button to swipe in. I am able to trigger my handler when left swipe the cell. The problem is that it doesn't trigger the editActionsForRowAtIndexPath where I am handling the code to create a button.
Instead, it goes to editingStyleForRowAtIndexPath and ends executing showing a red icon with a minus sign to the left of the cell.
My swipe handler and related code is as below:
- (void)swipeLeftDirection:(UIGestureRecognizer*)gesture
{
if (!tblInviteesTable.editing)
{
CGPoint location = [gesture locationInView: tblInviteesTable];
iPath = [tblInviteesTable indexPathForRowAtPoint:location];
// quitEditing = NO;
OpenHouseTableViewCell *currentCell = (OpenHouseTableViewCell *)[self tableView:tblInviteesTable cellForRowAtIndexPath:iPath];
[currentCell setEditing:YES];
[tblInviteesTable setEditing:YES animated:YES];
[self tableView:tblInviteesTable editActionsForRowAtIndexPath:iPath];
}}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(#"Handled editing style! %ld", (long)editingStyle);
} else {
NSLog(#"Unhandled editing style! %ld", (long)editingStyle);
}
}
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([tableView isEqual: tblInviteesTable]){
UITableViewRowAction *button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Resend" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"Resending email");
// [_delegate listingAgentsView: self selected: indexPath];
}];
button.backgroundColor = [UIColor redColor];
return #[button];
}
return #[];
}
Any help is greatly appreciated.

UITableView removing and adding rows

I have an NSMutableArray containing sequential numbers 1,2...,n and have a UITableView that displays cells vertically ascending and in order. How would I go about deleting a row, m between 1 and n, both visually and in the data, as well as in the NSMutableArray, and then decrement by 1 the value of all cells that followed the deleted cell in the data and visually such that the firstResponder does not resign control like a reloadData method call would?
#interface TableController : UIViewController
#property (nonatomic, retain) NSMutableArray *data;
#end
#implementation TableController
#synthesize data;
- (id)init
{
if(self = [super init]) {
data = [NSArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5",nil];
}
return self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [UITableViewCell new];
[cell.textLabel setText:[data objectAtRow:indexPath.row]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 20;
}
#end
How would I remove row 3 and then make rows four and five then become 3 and 4 respectively?
Just edit your view model and then reload the table.
[data removeObjectAtIndex:2];
[tableView reloadData];
Another option is the UITableView method deleteRowsAtIndexPaths:withRowAnimation:. This approach is UI only, you must also update your view model in case the cells ever get reloaded at a later time. The advantage of this approach is that only the cells you specify get changed. Existing cells are not reloaded.
If the cell you are deleting is your first responder then you could handle this case by telling the next cell to become first responder.
For user driven deletion, your [tableview dataSource] should implement the method tableView:commitEditingStyle:forRowAtIndexPath:.
Here's an implementation from my code…
-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(editingStyle == UITableViewCellEditingStyleDelete)
{
[[STLocationsModel sharedModel] deleteLocationAtIndex: [indexPath row]];
[tableView deleteRowsAtIndexPaths: #[indexPath] withRowAnimation: UITableViewRowAnimationLeft];
}
}
To allow editing, you'll also want…
-(BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
To get the table in to editing mode to allow deletions, you need to put it in to editing mode. You could place this in your viewDidLoad, or you might toggle it with a button:
[[self tableView] setEditing:YES animated:NO];
And if you also want to be able to make selections while the table is edited (again, this could go in your viewDidLoad…
[[self tableView] setAllowsSelectionDuringEditing: YES];

How to show in a UILabel what you Selected in a UITableViewCell (didSelectedRowAtIndexPath)

I am coding a registration form where users must enter their country. I listed the countries through a .plist file in a UITableView (Classe ViewController). In addition , I set the single selection with the checkmark. After selected the country the APP must go back and show in the country label the selected row (like a normal reg form).
Here whats under didSelectRowAtIndePath:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// Uncheck the previous checked row
if(self.checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:self.checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
if([self.checkedIndexPath isEqual:indexPath])
{
self.checkedIndexPath = nil;
}
else
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
}
Thanks for helping me.
Richard
If you have your label and your table in the same controller you can do this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self.yourLabel setText:[self.arrayCountries objectAtIndex:indexPath.row]];
}
but if you have your table and your label in differents controllers you can use NSUserDefaults for keep your selection like this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[[NSUserDefaults standardUserDefaults]setObject:[self.arrayCountries objectAtIndex:indexPath.row] forKey:#"selectedCountry"];
}
and in your controller where you have your label get this selection
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.labelCountry setText:[[NSUserDefaults standardUserDefaults] objectForKey:#"selectedCountry"]];
}
As I understood, you should use delegates. Once the country selected, call a delegate function in previous form and set the value of cell text.
e.g., (untested code to give an idea)
if(self.checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView cellForRowAtIndexPath:self.checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
if([self.checkedIndexPath isEqual:indexPath])
{
self.checkedIndexPath = nil;
}
else
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
// Trigger previous form to get the current form's data
// Here self.delegate takes address of previous form
[self.delegate setThisCountryNameToOwnerFormWithText:cell.titleLabel.text];
// Probably go back like this
// [self.navigationController popViewControllerAnimated:YES];
}
Just add that line like this
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
country.text=uncheckCell.label.text;//add this wherever you want, but it should be in this method only
}
where country is the label you created.
Also this line of code will work only if your label that is country and your table where you select the row both are in the same class,could you mention how you have made your classes like where your UITableView is?and where your UILabel is?

pop up a view when i clicked button on table view cell

I have a button on table view cell if I click the button a pop up view will be appeared and the remaining cells will be animated to downwards like animation.and the cell having sub views it will open like a plist in ios if i click the sub view cell it will open the next level sub cells. The tableview must be like below images
Cells and sub-cells must be like this. Can any one assist me?
I have done this before. Just use the following code. Create a custom cell class having the cell and followed view in the cell view but show only what is to be shown by using heightforrowatindexpath method uitableview class. Here is the code
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (checkHeight == indexPath.row)
return 185;
else
return 80;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
FAQCell *cell = (FAQCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"FAQCell" owner:self options:nil];
cell = myCell;
myCell = nil;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell.quesText setFont:[UIFont fontWithName:#"CaviarDreams" size:16]];
[cell.ansText setFont:[UIFont fontWithName:#"CaviarDreams" size:16]];
// check for the row for which the background color has to be changed
if (checkHeight == indexPath.row)
[cell.bgView setBackgroundColor:[UIColor colorWithRed:0.3333 green:0.7373 blue:0.4588 alpha:1.0]];
else
[cell.bgView setBackgroundColor:[UIColor colorWithRed:0.9176 green:0.3765 blue:0.2980 alpha:1.0]];
return cell;
}
#pragma mark -
#pragma mark Tableview Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Deselect cell
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
checkHeight = indexPath.row;
// reload the data of the table
[tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, tableView.numberOfSections)] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Let me know if you face any issue.
Check out this custom view -
Custom Tree View
Expandable Table View

Delete from UITableView using an NSFetchedResultsController

I have a UITableView which is populated through a NSFetchedResultsController. When the user slides an item to the right I have a delete button appearing so that he/she can remove the object using the following approach:
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//perform similar delete action as above but for one cell
XMPPUserCoreDataStorageObject *user = [[self fetchedResultsController] objectAtIndexPath:indexPath];
NSLog(#"User delete: %#", [user displayName]);
//delete from fetchController
NSArray *sections = [[self fetchedResultsController] sections];
int userStatus = [[user sectionNum] intValue];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
But when I do that there is an exception because I am not updating the model which is my fetchedResultsController. The question is how to remove from the fetchedController using the indexPath that I have from the commitEditingStyle ?
Since you are using NSFetchedResultsController you only need to delete the object from the context, and it will pick up the change and delete the rows for you.
So remove the deleteRowsAtIndexPaths: line and call this instead:
[self.fetchedResultsController.managedObjectContext deleteObject:user];
Have a look at this Answer , what you have to do is delete an NSManagedObject from your database as well as from the NSFetchedResultsController.