Reset UITableViewCell position - ios

-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
Course *c = self.courses[indexPath.row];
UITableViewRowAction *button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#" - " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
[c remove];
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
}];
button.backgroundColor = [UIColor red];
return #[button];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// you need to implement this method too or nothing will work
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES; //tableview must be editable or nothing will work...
}
How do I reset the position of my cell after the action has been pressed? Currently I'm reloading the cell but this ends up giving the cell a jumpy animation.

Related

Show multiple data, after swipe in tableview cell

I am having a table view with some datas. While on left swipe of cell i want 'Delete' and 'Edit'. I got 'Delete' by using the below code. Please help me to solve this..
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return NO;
}
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.circleGroupArray removeObjectAtIndex:indexPath.row];
[_myCircleTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Use this method in your class, If you want more actions you can create more UITableViewRowActions and add them to array.
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"Clona" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
//add edit action here
}];
editAction.backgroundColor = [UIColor blueColor];
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
//add delete action here
}];
deleteAction.backgroundColor = [UIColor redColor];
return #[deleteAction,editAction];
}

How to keep UITableViewCell textLabel position fixed on swipe?

How to keep UITableViewCell textLabel position fixed on swipe, while using Default UITableViewCell.
On swipe textLabel text goes left and outside the screen.
Related code:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//code related to delete row
}
}
Check images below for clear understanding:
Before swipe:
After swipe:
- (void)layoutSubviews
{
[super layoutSubviews];
CGSize size = self.bounds.size;
CGRect frame = CGRectMake(4.0f, 4.0f, size.width, size.height);
self.textLabel.frame = frame;
self.textLabel.contentMode = UIViewContentModeScaleAspectFit;
}
override this method...
I think contentView moves when you swipe, so try this:
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect frame = CGRectOffset(self.textLabel.frame,0-self.contentView.frame.x,0);
self.textLabel.frame = frame;
}
Please try this one:
#pragma mark- swipeable cell
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.frame=CGRectMake(30, 2, 50, 10);
UITableViewRowAction *unlink_button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
[self.accountsTable reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
cell.textLabel.frame=CGRectMake(0, 2, 50, 10);
[self deleteFunction];
}];
unlink_button.backgroundColor = [UIColor redColor]; //arbitrary color
return #[unlink_button];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// you need to implement this method too or nothing will work:
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}

UITableViewCell, show swipe-style delete button without swipe

I search couple of article but I didn't find what I'm looking for. Basically, I want to show delete button on each row but I don't want use UITableView.editing property.
Because it looks like this;
There will be "Edit" button. When user click on it, delete button will looks like swipe-style.
Is there any chance to show delete buttons like this;
Maybe there is a some way to deal with it. Otherwise, I'm going to create custom view for this.
Thanks for your advice.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//Do something...
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
Add a boolean property: #property BOOL didPressEdit;
Add UIButton to UITableViewCell
When pressing edit, didPressEdit becomes TRUE and UITableView reloads, such that cell.deleteButton.hidden = !didPressEdit; which makes all Delete buttons available
When pressing delete, remove object from datasource array, reload tableview
Hope this helps
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *moreAction2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"Edit" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[self.heartCartTabel setEditing:NO];
[self editButtonClicked:indexPath.row];
}];
moreAction2.backgroundColor = [UIColor blueColor];
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[self tableView:self.heartCartTabel commitEditingStyle: UITableViewCellEditingStyleDelete forRowAtIndexPath:indexPath];
// [self.heartCartTabel deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
return #[deleteAction, moreAction2];
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (IBAction)editButtonClicked:(int)indexNumber {
}
You can use a UITableView delegate method to ask for those actions. Implement this method as follows:
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *modifyAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
// Respond to the action.
}];
modifyAction.backgroundColor = [UIColor blueColor];
return #[modifyAction];
}
You can of course return multiple actions and customize the text and background color.
Implementing this method is also required to make the row editable:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
You need to call the method editActionsForRowAtIndexPath on your edit button click.
-(void)buttonTouched:(id)sender{
UIButton *btn = (UIButton *)sender;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:btn.tag inSection:0];
[self tableView:self.tableView editActionsForRowAtIndexPath:indexPath];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}

UITableViewCell custom edit content

I'd like my cells to have not only the Delete button while editing but also others. So what is an actual way to do this? I've tried making own UIView object for editingAccessoryView property but the problem is being that the view appears only on direct edit (i.e. clicking Edit button in Navigation Bar) and completely ignores swipes across a cell. Also tableView:editActionsForRowAtIndexPath: method was given a try but didn't work, at least I didn't manage to figure out how to get what I want with its function. Thank you in advance!
You Try This Code
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Button 1" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
NSLog(#"Action to perform with Button 1");
}];
button.backgroundColor = [UIColor greenColor]; //arbitrary color
UITableViewRowAction *button2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Button 2" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
NSLog(#"Action to perform with Button2!");
}];
button2.backgroundColor = [UIColor blueColor]; //arbitrary color
return #[button, button2]; //array with all the buttons you want. 1,2,3, etc...
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// you need to implement this method too or nothing will work:
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES; //tableview must be editable or nothing will work...
}
You CanTry also this code
.H File
{
NSMutableArray *dataArray;
}
#property (weak, nonatomic) IBOutlet UITableView *atableView;
#property(nonatomic,strong) NSMutableArray *dataArray;
**`.M file`**
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataArray = [[NSMutableArray alloc] initWithObjects:#"Saurabh Sharma",#"Deepesh Jain",#"Ashish Sharma",#"Chandan",#"kanhaiya",#"Suchitra Bohra",#"Neha",#"Ghanshyam",nil];
self.title = #"Move Rows";
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:#"Edit" style: UIBarButtonItemStyleBordered target:self action:#selector(editButton:)];
[self.navigationItem setRightBarButtonItem:editButton];
// Do any additional setup after loading the view from its nib.
}
-(void)editButton:(UIBarButtonItem *)button
{
{
if(self.editing)
{
[super setEditing:NO animated:NO];
[atableView setEditing:NO animated:NO];
[atableView reloadData];
[self.navigationItem.rightBarButtonItem setTitle:#"Edit"];
[self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStylePlain];
}
else
{
[super setEditing:YES animated:YES];
[atableView setEditing:YES animated:YES];
[atableView reloadData];
[self.navigationItem.rightBarButtonItem setTitle:#"Done"];
[self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStyleDone];
}
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dataArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifair=#"cellIdentifair";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifair];
if(cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifair];
}
cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
#pragma delete row in table view
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionView *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 10; // This is the minimum inter item spacing, can be more
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return TRUE;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
[dataArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[tableView endUpdates];
NSLog(#"Methods called when row is deleted");
}
#pragma Move Table View Delegte
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
NSString *item = [self.dataArray objectAtIndex:fromIndexPath.row];
[self.dataArray removeObject:item];
[self.dataArray insertObject:item atIndex:toIndexPath.row];
}
Works in Swift as well.
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var completionButton = UITableViewRowAction(style: .Normal,
title: "Complete",
handler: {(action, index) in
/* Completion Code */
println("Complete")})
completionButton.backgroundColor = .lightGrayColor()
return [completionButton]
}
Also for iOS 11 you should use
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath - for right swipe
and
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath - for left swipe
For ex.:
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
UIContextualAction* action = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:#"Title" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
// Do something
completionHandler(YES);
}
UISwipeActionsConfiguration * actionsConfiguration = [UISwipeActionsConfiguration configurationWithActions:#[action]];
return actionsConfiguration;
}

UITableViewCell not respecting shouldIndentWhileEditing = NO?

I've been trying to stop the (-) delete indicator from showing up when I put a UITableView into editing mode.
Updates for clarity:
This is what the table looks like:
This is what I have setup in - (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
When I tap reorder, I go into edit mode. I don't want these to show:
I've worked around the the 3rd screenshot by limiting the buttons shown from editActionsForRowAtIndexPath to just delete, but I don't even want to get to this part. I want Edit mode to be reorder only
/Updates
I've tried setting UITableViewCell.shouldIndentWhileEditing = NO
On the Cell directly:
cell.indentationLevel = -3;
cell.shouldIndentWhileEditing = NO;
In interface builder
In the appropriate delegate method
- (BOOL)tableView:(UITableView *)tableview shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"shouldIndentWhileEditingRowAtIndexPath");
return NO;
}
I'm also showing over items in the actions list. I hadn't planned on having delete at all when in Editing mode, just reodering. I've adjusted a few things so I only show the delete when a user swipes, but I'd rather the (-) not show at all:
- (void) endEditing
{
self.editMode = NO;
self.editControlButton.title = #"Reorder";
[self setEditing:NO animated:YES];
//[self.tableView reloadData];
}
- (void) startEditing
{
self.editMode = YES;
self.editControlButton.title = #"Done";
[self.tableView setEditing:YES animated:YES];
}
#pragma - mark UITableViewDelegate
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (BOOL)tableView:(UITableView *)tableview shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"shouldIndentWhileEditingRowAtIndexPath");
return NO;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
TCORead *item = [self.fetchedResultsControllerDataSource selectedItem];
manager.currentRead = item;
}
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[self.tableView setEditing:NO];
}];
//workaround, rdar://17969970
//normally don't want to be able to get into this menu when reordering
if (!self.editMode) {
UITableViewRowAction *shareAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"Share" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[self.tableView setEditing:NO];
}];
shareAction.backgroundColor = [UIColor grayColor];
UITableViewRowAction *doneAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:#"Done" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[self.tableView setEditing:NO];
}];
doneAction.backgroundColor = [UIColor greenColor];
[self startEditing];
return #[deleteAction, doneAction, shareAction];
}
return #[deleteAction];
}
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
[self endEditing];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//empty on purpose
}
I was forcing the delete indicator to appear. Vanyas has a sample project that showed me what I was doing wrong.
My editingStyleForRowAtIndexPath method needed to look like this:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath: (NSIndexPath *)indexPath
{
//return UITableViewCellEditingStyleDelete;
return tableView.isEditing ? UITableViewCellEditingStyleNone: UITableViewCellEditingStyleDelete;
}
If you don't want to allow deleting, just reordering, then there is no need to do anything about indenting. Instead, just do:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
And don't implement the tableView:commitEditingStyle:forRowAtIndexPath: method at all.
You also avoid returning deleteAction from tableView:editActionsForRowAtIndexPath:.
That will prevent row deletion. You can now support reordering as needed.

Resources