objective c remove copy button from menu bar - ios

I'm writing an application that uses webkit to read epubs. When I'm selecting text by long press , the menu bar opens, and there should only be Facebook, and Twitter buttons. So here is my code how do I did it :
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if (action == #selector(facebookItemClicked:) || action == #selector(twitterItemClicked:)) {
return YES;
}else if (action == #selector(copy:)){
NSLog(#"copy");
} return NO;}
Here is how I initialize menu Items
UIMenuItem *facebookMenuItem = [[UIMenuItem alloc] initWithTitle:#"Facebook" action:#selector(facebookItemClicked:)];
UIMenuItem *twitterMenuItem = [[UIMenuItem alloc] initWithTitle:#"Twitter" action:#selector(twitterItemClicked:)];
But the problem is that copy selector never appears it as action so I cannot catch it and every time menu bar is shown there is also a copy button beside Facebook and Twitter.
It would be great if someone could help me.
Thanks in advance.

Solved problem.
Default UIWebView was overriding my menuBar actions. So I created a class CustomWebView inherited from UIWebView added
+ (void)initialize{
UIMenuItem *itemA = [[UIMenuItem alloc] initWithTitle:#"A" action:#selector(a:)];
UIMenuItem *itemB = [[UIMenuItem alloc] initWithTitle:#"B" action:#selector(b:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:itemA, itemB, nil]];
// [itemA release];
// [itemB release];
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
BOOL can = [super canPerformAction:action withSender:sender];
if (action == #selector(a:) || action == #selector(b:))
{
can = YES;
}
if (action == #selector(copy:))
{
can = NO;
}
NSLog(#"%# perform action %# with sender %#.", can ? #"can" : #"cannot", NSStringFromSelector(action), sender);
return can;
}
which overrides menubar actions in webview and then I use this CustomWebView in other classes that use webvew.

Related

how to make a delete popover view like the one in the attached picture in iOS?

I want to make this view.
How should I do?
When I click the tag, and pop "delete" .
Following code will help you to achieve what you want:
CGRect rect=CGRectMake(0, 0, 100, 50);
UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:#"Delete" action:#selector(btnDelete:)];
UIMenuController *menuCont = [UIMenuController sharedMenuController];
[menuCont setTargetRect:CGRectMake(30, rect.origin.y+10, 130, 20) inView:yourView];
menuCont.arrowDirection = UIMenuControllerArrowUp;
menuCont.menuItems = [NSArray arrayWithObjects:menuItem,nil];
[menuCont setMenuVisible:YES animated:YES];
Also you need to specify the delegates.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
BOOL retValue = NO;
if (action == #selector(paste:) )
retValue = NO ;
else if ( action == #selector(cut:) || action == #selector(copy:) )
retValue = NO;
else
retValue = [super canPerformAction:action withSender:sender];
return retValue;
}
Present the alert controller as pop over. Put only one button in alert controller, set background colour as black. Using this definitely you will get result. But I don't know is this is the correct solution for that?.

How to show custom menu items from starting in iOS?

How to remove default menu items like copy, past, SelectAll when i select WebView content. How to put custom actions in middle of default menu items.Which items i'm putting these are showing in last, i want to my custom actions from starting.
I'm using below code in view didAppear method.
UIMenuItem *customMenuItem1=[[UIMenuItem alloc] initWithTitle:#"Highlight" action:#selector(customAction1:)];
UIMenuItem *customMenuItem2=[[UIMenuItem alloc] initWithTitle:#"UnHighlight" action:#selector(UnHighlighted:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:customMenuItem1,customMenuItem2,nil]];
[UIMenuController sharedMenuController].menuVisible=YES;
Please help me.
As answered here showing custom menu on selection in UIWebView in iphone
- (void)viewDidLoad {
[super viewDidLoad];
[self.webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"https://www.google.com"]]];
self.webview.backgroundColor = [UIColor blueColor];
// Do any additional setup after loading the view.
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIMenuItem *customMenuItem1 = [[UIMenuItem alloc] initWithTitle:#"Custom 1" action:#selector(customAction1:)];
UIMenuItem *customMenuItem2 = [[UIMenuItem alloc] initWithTitle:#"Custom 2" action:#selector(customAction2:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:customMenuItem1, customMenuItem2, nil]];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[[UIMenuController sharedMenuController] setMenuItems:nil];
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (self.webview.superview != nil)// && ![urlTextField isFirstResponder])
{
if (action == #selector(customAction1:) || action == #selector(customAction2:))
{
return YES;
}
}
return [super canPerformAction:action withSender:sender];
}
-(void)customAction1:(UIMenuItem*)item
{}
-(void)customAction2:(UIMenuItem*)item
{}

IOS:Create subMenu using UIMenuItemController inside a UIWebView

I would like the behaviour is that:
When I click on my custom UIMenuItem, it would show another list of UIMenuItems to choose.
I have implemented in that way.
#implementation CustomUIWebView{
BOOL clickedShowSubMenu;
NSArray *mainMenuItems;
NSArray *subMenuItems;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if(self){
UIMenuController *mc = [UIMenuController sharedMenuController];
UIMenuItem *testSubMenu = [[UIMenuItem alloc] initWithTitle:#"TestSubMenu" action:#selector(testSubMenu:)];
mainMenuItems = [NSArray arrayWithObjects:testSubMenu, nil];
UIMenuItem *subItem1 = [[UIMenuItem alloc] initWithTitle:#"Item1" action:#selector(item1:)];
UIMenuItem *subItem2 = [[UIMenuItem alloc] initWithTitle:#"Item2" action:#selector(item2:)];
subMenuItems = [NSArray arrayWithObjects:subItem1, subItem2, nil];
[mc setMenuItems:mainMenuItems];
[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onMenuItemDismissed:) name:UIMenuControllerDidHideMenuNotification object:nil];
clickedShowSubMenu = NO;
}
return self;
}
- (void)testSubMenu:(id)sender{
UIMenuController *mc = [UIMenuController sharedMenuController];
[mc setMenuItems:subMenuItems];
mc.menuVisible = YES; //from te doc, it say it would keep the menu not dismiss when this function end
clickedShowSubMenu = YES;
}
- (void)item1:(id)sender{
}
- (void)item2:(id)sender{
}
- (void)onMenuItemDismissed:(id)sender{
if(clickedShowSubMenu == YES){
UIMenuController *mc = [UIMenuController sharedMenuController];
[mc setMenuItems:mainMenuItems];
clickedShowSubMenu = NO;
}
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
if(action == #selector(testSubMenu:))return YES;
else if(action == #selector(item1:))return YES;
else if(action == #selector(item2:))return YES;
return NO;
}
#end
It works when I select long touch some text and click the Test Sub Menu, it did appear the "subMenu": Item1 and Item2 on the same position that Test Sub Menu appear.
However, the problem is the second time and later. I select other text and the Test Sub Menu appear correctly, but when I click it ,the Item1 and Item2 is showed on the OLD position that it first appear. Their position is never changed. I do not know what cause this.
EDIT
Ok. By making use of How to get coordinates (CGRect) for the selected text in UIWebView? to get the rect boundary of the selection and say [mc setTargetRect:theRect inView:self]; before mc.menuVisible = YES;
It work and the sub menu show approximate same position of the main menu. Is it recommended? There is still little problem that when I highlight a whole paragraph, the main menu is show UNDER the paragraph, however, the sub menu show ABOVE the paragraph.

iOS: How to get the selected UIMenuItem from UIMenuController

I am trying to use UIMenuCnotroller to show a list of dynamically generated items, they share the same action method, and so I need to know which item is selected in the single action method.
However, in the action method - (void)menuItemAction:(id)sender;the sender is actually the UIMenuController object, and I didn't find any method of UIMenuController can tell me which menuitem is selected.
One solution I can think of is to dynamically generate different action selectors for different items, and do some tricks in forwardInvocation
But is there any easier way?
You can use UIMenuCnotroller like:
1) creation:
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *open = [[UIMenuItem alloc] initWithTitle:#"Open" action:#selector(open:)];
UIMenuItem *reDownload = [[UIMenuItem alloc] initWithTitle:#"Re-Download" action:#selector(reDownload:)];
[menuController setMenuItems:[NSArray arrayWithObjects:open, reDownload, nil]];
[menuController setTargetRect:cell.frame inView:self.view];
[menuController setMenuVisible:YES animated:YES];
[open release];
[reDownload release];
2) To catch actions should implement next methods:
- (BOOL) canPerformAction:(SEL)selector withSender:(id) sender
{
if (selector == #selector(open:))
{
return YES;
}
if (selector == #selector(reDownload:))
{
return YES;
}
return NO;
}
- (BOOL) canBecomeFirstResponder
{
return YES;
}
3) And realization of yours methods:
- (void) open:(id) sender
{
[self doSomething];
}
- (void) reDownload:(id) sender
{
[self doSomething];
}
Hope, this helps.
Okay, I've solved this one. It involves messing with [NSObject forwardInvocation:] and is a bit dirty, but the resulting code is quite minimal. Answered over here: https://stackoverflow.com/a/9874092/790036
One easiest way would be to use different #selector method for each menu item
Examples:
UIMenuItem *oneObj = [[UIMenuItem alloc] initWithTitle:#"One" action:#selector(One:)];
UIMenuItem *twoObj = [[UIMenuItem alloc] initWithTitle:#"Two" action:#selector(Two:)];

Customize select,copy/paste in iPad

I am working on eBook App in iPad,And using UIMenuController.And i want to customize select,copy and paste function which default in menu-controller. I am not able to customize that function Please help me out with source code
Thanks
Kunal
Derive UITextView as follows.
//MyUITextView.h
#import <Foundation/Foundation.h>
#interface MyUITextView : UITextView {
}
#end
//MyUITextView.m
#import "MyUITextView.h"
#implementation MyUITextView
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == #selector(menu1:))
return YES;
if (action == #selector(menu2:))
return YES;
return NO;//[super canPerformAction:action withSender:sender];
}
- (void)menu1:(id)sender
{
NSLog(#"in menu1");
}
- (void)menu2:(id)sender
{
NSLog(#"in menu2");
}
#end
In your view controller under viewDidLoad
UIMenuItem *menu1 = [[[UIMenuItem alloc] init]autorelease];
menu1.title = #"MyMenu1";
menu1.action = #selector(menu1:);
UIMenuItem *menu2 = [[[UIMenuItem alloc] init]autorelease];
menu2.title = #"MyMenu2";
menu2.action = #selector(menu2:);
UIMenuController* mc = [UIMenuController sharedMenuController];
mc.menuItems = [NSArray arrayWithObjects: menu1, menu2, nil];
You need to assign class to your TextView from interfacebuilder if it is on nib and if you create it dynamically create object of MyUITextView instead of UITextView.
Above code adds 2 custom menu while you select text and when you select option it will fire selector accordingly.
Hope it helps.

Resources