Segue from editActionsForRowAtIndexPath - ios

I'm making a little banking type app, for instructional purposes.
All transactions are stored as Core Data entities, fetched and sorted using Magical Record helper methods. The transactions are displayed in a UITableView, fed by a fetchedObjects array.
I want to be able to use editActionsForRowAtIndexPath like so:
The first action segues to another uiviewController, the second and third to a UIPopoverPresentationController. The fourth button deletes the transaction.
EDIT
Here's the code to create the buttons:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
//Obviously, if this returns no, the edit option won't even populate
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//Nothing gets called here if you invoke `tableView:editActionsForRowAtIndexPath:` according to Apple docs so just leave this method blank
}
-(NSArray *)myArray:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Delete code here
}];
UITableViewRowAction *changeAmt = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Amt" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// popover amount change code
}];
changeAmt.backgroundColor = [UIColor colorWithRed:0.022 green:0.541 blue:0.001 alpha:1.00];
UITableViewRowAction *changeAcct = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Acct" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// popover account change code
}];
changeAcct.backgroundColor = [UIColor colorWithRed:1.000 green:0.492 blue:0.000 alpha:1.00];
UITableViewRowAction *viewTrans = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"View" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Push to view
}];
viewTrans.backgroundColor = [UIColor colorWithRed:0.002 green:0.342 blue:0.710 alpha:1.00];
return #[delete, changeAmt,changeAcct,viewTrans]; //array with the buttons delete, changeAmt, changeAcct, viewTrans
}
Here's my question:
How do I tell which button to trigger which segue? I can't figure how to make the connections.
Here's a representative chunk of code from my prepareForSegue. One point of my confusion is indicated by the ??? in the argument for the sourceRect:
else if ([[segue identifier] isEqualToString:#"AmountPopSegue"])
{
UIViewController *controller = segue.destinationViewController;
controller.popoverPresentationController.delegate = self;
controller.preferredContentSize = CGSizeMake(320, 186);
UIPopoverPresentationController *thisPPC = controller.popoverPresentationController;
thisNavController = (UINavigationController *)segue.destinationViewController;
AmountChangePopVC *acVC = (AmountChangePopVC *)thisNavController.topViewController;
acVC.delegate = self;
thisPPC.sourceRect = ???;
}
All insights appreciated. I'm writing in Objective C because I started this project before Swift became all the rage.

This method can help you. You'll know which button was tapped.
--Be careful. this method only work in iOS 8 or later.--
#property (nonatomic, strong) NSIndexPath *firstButtonIndexPath;
#property (nonatomic, strong) NSIndexPath *secondButtonIndexPath;
#property (nonatomic, strong) NSIndexPath *thirdButtonIndexPath;
#property (nonatomic, strong) NSIndexPath *fourthButtonIndexPath;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
if (self.firstButtonIndexPath) {
NSLog(#"ViewButton :%ld", (long)self.firstButtonIndexPath.row);
} else if (self.secondButtonIndexPath) {
NSLog(#"Acct :%ld", (long)self.secondButtonIndexPath.row);
} else if (self.thirdButtonIndexPath) {
NSLog(#"Amt :%ld", (long)self.thirdButtonIndexPath.row);
} else if (self.fourthButtonIndexPath) {
NSLog(#"Delete :%ld", (long)self.fourthButtonIndexPath.row);
}
}
}
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
self.firstButtonIndexPath = nil;
self.secondButtonIndexPath = nil;
self.thirdButtonIndexPath = nil;
self.fourthButtonIndexPath = nil;
UITableViewRowAction *viewAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"View" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"View the row");
self.firstButtonIndexPath = indexPath;
}];
viewAction.backgroundColor = [UIColor blueColor];
UITableViewRowAction *acctAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Acct" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"Acct the row");
self.secondButtonIndexPath = indexPath;
}];
acctAction.backgroundColor = [UIColor orangeColor];
UITableViewRowAction *amtAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Amt" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"Amt the row");
self.thirdButtonIndexPath = indexPath;
}];
amtAction.backgroundColor = [UIColor greenColor];
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"Delete the row");
self.fourthButtonIndexPath = indexPath;
}];
deleteAction.backgroundColor = [UIColor redColor];
return #[deleteAction, amtAction, acctAction, viewAction];
}

Related

How to set the action of UITableViewRowAction

I customized my UITableCellDeleteConfirmationView to change the background color of the button in iOS 8 and above. Following this post, I implemented editActionsForRowAtIndexPath, commitEditingStyle and canEditRowAtIndexPath.
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
RankedSpecies* rankedSpecies = [fetchedResultsController objectAtIndexPath:indexPath];
if ( [self.collectedLeaf.selectedSpecies isEqualToString:[rankedSpecies.Species commonNameFirstLast]] )
{
UITableViewRowAction *unlabelSpecies = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"UnLabel" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
NSLog(#"Action to perform with Button 1");
}];
unlabelSpecies.backgroundColor = [UIColor darkGrayColor];
return #[unlabelSpecies];
}
UITableViewRowAction *labelSpecies = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"Label" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
NSLog(#"Action to perform with Button 1");
}];
labelSpecies.backgroundColor = [UIColor darkGrayColor];
return #[labelSpecies];
}
However, when I push these custom buttons, they do not call commitEditingStyle. According to this post, commitEditingStyle is only fired when you touch the delete button.
Instead of trying to figure out how to fire commitEditingStyle, I have created methods that replicate my commitEditingStyle implementation, removeCollectedLeafLabel. Can a class method be an action? How do I set the UITableViewRowAction to do something when pressed?
when your press button it will call the block.
UITableViewRowAction *unlabelSpecies = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"UnLabel" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
CALL_YOUR_METHOD_FROM_HERE
}];
unlabelSpecies.backgroundColor = [UIColor darkGrayColor];
return #[unlabelSpecies];

Disappearing editActionsForRowAtIndexPath actions

I want to implement editActionsForRowAtIndexPath to display several options when I left-swipe a cell in my UITableview. So I used this code:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
//Obviously, if this returns no, the edit option won't even populate
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//Nothing gets called here if you invoke `tableView:editActionsForRowAtIndexPath:` according to Apple docs so just leave this method blank
}
-(NSArray *)tableview:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Delete code here
}];
UITableViewRowAction *changeAmt = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Amt" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// popover amount change code
}];
changeAmt.backgroundColor = [UIColor colorWithRed:0.022 green:0.541 blue:0.001 alpha:1.00];
UITableViewRowAction *changeAcct = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Acct" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// popover account change code
}];
changeAcct.backgroundColor = [UIColor colorWithRed:1.000 green:0.492 blue:0.000 alpha:1.00];
UITableViewRowAction *viewTrans = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"View" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Push to view
}];
viewTrans.backgroundColor = [UIColor colorWithRed:0.002 green:0.342 blue:0.710 alpha:1.00];
return #[delete,changeAmt,changeAcct,viewTrans]; //array with the buttons delete, changeAmt, changeAcct, viewTrans
}
Yesterday, this code produced this result:
Today, I decided to eliminate the viewTrans action by modifying the editActionsForRowAtIndexPath method like this:
-(NSArray *)tableview:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Delete code here
}];
UITableViewRowAction *changeAmt = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Amt" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// popover amount change code
}];
changeAmt.backgroundColor = [UIColor colorWithRed:0.022 green:0.541 blue:0.001 alpha:1.00];
UITableViewRowAction *changeAcct = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Acct" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// popover account change code
}];
changeAcct.backgroundColor = [UIColor colorWithRed:1.000 green:0.492 blue:0.000 alpha:1.00];
// UITableViewRowAction *viewTrans = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"View" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
// {
// // Push to view
// }];
// viewTrans.backgroundColor = [UIColor colorWithRed:0.002 green:0.342 blue:0.710 alpha:1.00];
return #[delete,changeAmt,changeAcct]; //array with the buttons delete, changeAmt, changeAcct, viewTrans
}
This modified code had the effect, somehow, of removing all the actions except the default Delete action:
So I uncommented the code, and replaced the reference to the viewTrans action in the return line. The extra actions do not reappear.
This is the only code I modified. Anybody have any idea what I did wrong?
I had been working on your question and initially, I can't get editActionsForRowAtIndexPath method called but later I found a little problem and maybe is the same for you, the declaration for the method
-(NSArray *)tableview:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
is not right, the correct is
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
so my method stay like this
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Delete code here
}];
UITableViewRowAction *changeAmt = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Amt" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// popover amount change code
}];
changeAmt.backgroundColor = [UIColor colorWithRed:0.022 green:0.541 blue:0.001 alpha:1.00];
UITableViewRowAction *changeAcct = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Acct" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// popover account change code
}];
changeAcct.backgroundColor = [UIColor colorWithRed:1.000 green:0.492 blue:0.000 alpha:1.00];
//UITableViewRowAction *viewTrans = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"View" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
// {
// Push to view
// }];
//viewTrans.backgroundColor = [UIColor colorWithRed:0.002 green:0.342 blue:0.710 alpha:1.00];
return #[delete,changeAmt,changeAcct]; //array with the buttons delete, changeAmt, changeAcct, viewTrans
}
And this is how it looks
I hope this helps you

UIButton touchUpInside conflicts with UITableViewCell swipe event

I am displaying swipe button in UITableViewCell as follows :
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *cancelAction;
UITableViewRowAction *editAction;
UITableViewRowAction *messageAction;
cancelAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"Cancel" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[tableActivities setEditing:NO];
}];
cancelAction.backgroundColor = [UIColor blueColor];
editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:#"Edit" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[tableActivities setEditing:NO];
}];
editAction.backgroundColor = [UIColor greenColor];
messageAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:#"Message" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
[tableActivities deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
return #[messageAction, cancelAction, editAction];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
}
In the cell's contentView, I have placed a UIButton which has a UIControlEventTouchUpInside controlEvent.
When I swipe the cell by touching the button area, both the swipe and UIButton event are fired.
How can I control this ?
You can solved your problem by checking isEditing property of UITableView in your button action like this
- (void)btnTap:(UIButton*) sender {
if (!self.tableActivities.isEditing) {
//Perform Action
}
}

Localization and RTl layout changing tableview works on simulator but not real decive

I used the localization and RTl layout to change the tableview when i tested on simulator it works good but when I tested on real device it doesn't work. Why is this?
(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Edit" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
// show UIActionSheet
NSLog(#"im pressed the edit");
}];
editAction.backgroundColor = [UIColor grayColor];
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:#"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
// flag the row
NSLog(#"im pressed the delete/");
}];
deleteAction.backgroundColor = [UIColor redColor];
return #[editAction, deleteAction];
}

UITableViewRowAction change backgroundcolor on press

I created an instance of UITableViewRowAction in
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
and I have a handler block when this row action is triggered:
handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
You have a row action parameter that can be used so you do not create retain cycles and you have an index path. I've tried setting the backgroundColor of that new row action like this:
[action setBackgroundColor:[UIColor greenColor]];
But this did not change anything. I also tried setNeedsDisplay on the button object of the row action, but without any luck.
Any idea how I can change the backgroundColor while the row actions are still visible? Thanks
xCoder
Here is my implementation of the same and it works well. It should solve your problem as well..
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewRowAction *one = [UITableViewRowAction rowActionWithStyle:0 title:#"one" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"my first action");
}];
UITableViewRowAction *two = [UITableViewRowAction rowActionWithStyle:1 title:#"two" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"my second action");
}];
UITableViewRowAction *three = [UITableViewRowAction rowActionWithStyle:1 title:#"three" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
NSLog(#"my third action");
}];
one.backgroundColor = [UIColor purpleColor];
two.backgroundColor = [UIColor greenColor];
three.backgroundColor = [UIColor brownColor];
return #[one, two, three];
}

Resources