I am working on adding custom shared menu. I followed this stackoverflow post to implement this also seen some other posts.
It is working as it should be. But I am getting problem to get called canPerformAction when coming on this UITableView Controller by UITabBar item action which navigate me back to this view.
I tried to sovle this problem by using one of the answer on stackoverflow. But still canPerformAction not getting called in this case
Any help in this case is appritiated. Thanks
EDIT: My code looks like:
On viewDidLoad, i am doing following
UIMenuItem *sendByEmailMenuItem = [[UIMenuItem alloc] initWithTitle:#"Send e-mail" action:#selector(sendEmail:)];
[[UIMenuController sharedMenuController] setMenuItems: #[sendEmailMenuItem]];
[[UIMenuController sharedMenuController] update];
These are delegate methods i have used
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
return NO;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
}
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender {
return (action == #selector(sendEmail:));
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void) sendEmail: (id) sender {
//do stuff
}
Fixed this issue. Posting it if some one needs it.
I have added a call to become fist respoder on shouldShowMenuForRowAtIndexPath action
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
[self becomeFirstResponder];
return YES;
}
This fixed my issue. Thanks
Related
I have a default edit button on the top left of my navigation bar. When it is pressed, the damn table does not show the indentation the first time. When I press "done" it does! How do i fix this?
Here is my code:
- (void)viewDidLoad {
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}
#pragma mark edit
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[_tableView setEditing:editing animated:animated];
}
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (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
{
}
EDIT
Overriding these two methods in the UITableViewCell subclass removes the indentation for me.
- (void)willTransitionToState:(UITableViewCellStateMask)state
- (void)didTransitionToState:(UITableViewCellStateMask)state
So I can now make my own animation.
Overriding these two methods in the UITableViewCell subclass removes the indentation for me.
- (void)willTransitionToState:(UITableViewCellStateMask)state
- (void)didTransitionToState:(UITableViewCellStateMask)state
So I can now make my own animation.
I am developing an app where on click of table cell i am displaying UIMenuItem with 'Info' button. Now on clicking the info button i have to show a view and dismiss on click of cancel.
In MytableView(Custom tableView)
-(void)tableView : (UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"didSelectRow");
UIMenuItem *testMenuItem = [[UIMenuItem alloc] initWithTitle:#"Info" action:#selector(handleInfo:)];
[[UIMenuController sharedMenuController] setMenuItems: #[testMenuItem]];
[[UIMenuController sharedMenuController] update];
}
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
-(BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
// if (action == #selector(handleInfo:))
// {
// return YES;
// }
return NO;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
// required
}
-(IBAction)handleInfo:(id)sender{
InfoViewController *readInfo = [[InfoViewController alloc] initWithNibName:#"InfoViewController" bundle:nil];
readInfo.label.text = #"Info of table cell";
[myAppDelegate.navController pushViewController:readInfo animated:NO];
}
I am able to push the view but unable to dismiss it and value passed to readInfo.label.text is returning null.
1.
readInfo.label.text is returning null. Because at this time the label in xib still not rendered.
to solve this, can assign the text after pushViewController.
but i would prefer to pass the text in the initWithNib method.
may be create another method initWithNibName:#"xxx" text:#"Info of table cell";
store it in InfoViewController, and assign this text to it in viewDidLoad.
2.
what method did you call when dismiss that InfoViewController??
[myAppDelegate.navController popViewController]
this should do the trick.
I have implemented UITableview edit mode when a button is clicked but every time it goes to edit mode and I click on the deletion button, nothing happens. I have a view controller with a UITableview on it. I have set my delegate and tableview source as well as all of my editing callbacks. Everything is working (like reordering cells) but whenever I try to delete by pressing the delete control button, the delete button doesn't show up.
I am desperate since it seems like a really simple problem but no matter what I try it doesn't seem to work.
This is how I am implementing edit mode
- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:
(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[favoriteCurrencyValueList removeObjectForKey:[favoriteCurrencyList objectAtIndex:indexPath.row]];
[favoriteCurrencyList removeObjectAtIndex:indexPath.row];
NSUserDefaults *defaultSettings = [NSUserDefaults standardUserDefaults];
[defaultSettings setObject:favoriteCurrencyList forKey:#"FavoriteCurrencies"];
[defaultSettings setObject:favoriteCurrencyValueList forKey:#"PastValues"];
[defaultSettings synchronize];
[self.favoriteCurrencyTable beginUpdates];
[self.favoriteCurrencyTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:(UITableViewRowAnimation)UITableViewRowAnimationLeft];
[self.favoriteCurrencyTable endUpdates];
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
indexPathSelected = indexPath;
//[self.view endEditing:YES];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
[self.favoriteCurrencyList exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];
[[NSUserDefaults standardUserDefaults] setObject:self.favoriteCurrencyList forKey:#"FavoriteCurrencies"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
This is what sets the edit mode
- (IBAction)editButtonPressed:(UIBarButtonItem *)sender {
if (self.editing && self.favoriteCurrencyTable.editing) {
self.editing = NO;
[self.favoriteCurrencyTable setEditing:NO animated:YES];
[self.editButton setTitle:#"Edit"];
}
else {
self.editing = YES;
[self.favoriteCurrencyTable setEditing:YES animated:YES];
[self.editButton setTitle:#"Done"];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if (([touch.view isKindOfClass:[UIButton class]] && touch.view.tag==<Button_TAG>)) {
// prevent recognizing touches on the slider
return NO;
}
return YES;
}
For tap gestures add the delegate and write the above code.
You need to implement the following method:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
} 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
}
}
If delete does not work then it is a problem of your table view delegate or datasource methods called.Check these methods should definitely be called
1.tableView:editingStyleForRowAtIndexPath:
2.tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:
3.tableView:shouldIndentWhileEditingRowAtIndexPath:
You try to check if titleforDeleteConfirmationbutton is called at every time you click edit and check how many times it calls and also check if you are giving indent return value as yes in shouldIndentwhileediting method.
check your gesture recognizers.
I have a uitableviewdelegate class that is delegate of two uitableview. I want that one of them has remove button and the other do not have remove button. I used below code:
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
if(tableView==self.firstTableView){
return #"Remove";
}else
return #"";
}
button my code do not disable editing style for secondTableView it just set empty text as title. How can I do this?
EDIT
I also use below methods:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == slef.FirstTableView){
//Some codes
}
}
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == self.FirstTableView){
//Some codes
}
}
but any of them was not helpful.
Please implement this delegate method.
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView==self.firstTableView) {
return NO;
}
return YES;
}
Use delegate method
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
Here you can return UITableViewCellEditingStyleNone or UITableViewCellEditingStyleDelete for desired table
Is there a simple way to implement the copy menu when a cell is tapped, instead of subclassing the UITableViewCell?
thanks,
RL
In iOS 5, a simple way is to implement the UITableViewDelegate Methods:
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
By implementing the 3 delegates, it will enable call UIMenuController for you after a long press gesture. An example like:
/**
allow UIMenuController to display menu
*/
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
/**
allow only action copy
*/
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
return action == #selector(copy:);
}
/**
if copy action selected, set as cell detail text
*/
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
if (action == #selector(copy:))
{
UITableViewCell* cell = [tableView cellForIndexPath:indexPath];
[[UIPasteboard generalPasteboard] setString:cell.detailTextLabel.text];
}
}
Yes!
Call [[UIMenuController sharedMenuController] setMenuVisible:YES animated:ani] (where ani is a BOOL determining whether the controller should be animated) from within - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath ( UITableView's delegate method)
Edit: The 'copy' command on the UIMenuController will not by default copy the detailTextLabel.text text. However, there is a workaround. Add the following code into your class.
-(void)copy:(id)sender {
[[UIPasteboard generalPasteboard] setString:detailTextLabel.text];
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if(action == #selector(copy:)) {
return YES;
}
else {
return [super canPerformAction:action withSender:sender];
}
}