The Custom UIMenuItem is too wide in IOS5 - ios5

I have a UIWebView in my app,and it can perform the UIMenuController. And I add a Custom UIMenuItem to the UIMenuController(like "google it").
The code I add the UIMenuItem is:
UIMenuItem *searchItem = [[UIMenuItem alloc] initWithTitle:#"google it" action:#selector(searchWithSelectedText)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:searchItem]];
[searchItem release];
Now,the custom UIMenuItem can be shown and do the right thing after clicked.
But in ios5,the UIMenuItem is too wide when it be shown.
Can the custom UIMenuItem be set shorter like the system items?
Thanks.

This is the new system style, I don't think you can customize it.

Related

Adding Speech to custom UIMenuController

I created a custom UIMenuController in a UIWebView but it seems to get rid of the "Speak Selection" option in the UIMenuController after that. The speak selection option is turned on in Preferences on all test devices and it appears in other apps, including non-Apple apps. Is there an accessibility service or part of the sharedMenuController that I can call to get this item?
UIMenuItem *copyMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(#"Copy", #"Copy menu item") action:#selector(myappCopy:)];
UIMenuItem *highlightMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(#"Highlight", #"Highlight menu option") action:#selector(myappHighlight:)];
UIMenuItem *unhighlightMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(#"Remove Highlight", #"Remove Highlight menu option")
action:#selector(myappRemoveHighlight:)];
UIMenuItem *noteMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(#"Note", #"Note menu options") action:#selector(myappNote:)];
[UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObjects:copyMenuItem, highlightMenuItem, unhighlightMenuItem, noteMenuItem, nil];
[copyMenuItem release];
[highlightMenuItem release];
[unhighlightMenuItem release];
[noteMenuItem release];
I even tried to parse the existing shared menu items at the start, but I don't see anything dumped in the log. The method is getting called on app launch.
Tried this at top of method:
for (UIMenuItem *menuItem in [UIMenuController sharedMenuController].menuItems) {
NSLog(#"title: %#", menuItem.title);
NSLog(#"action: %#", menuItem.action);
}
Any help is much appreciated! Thanks - Eric
I've found some interesting things with this bug. Basically, when speak selection is enabled, after you make the first selection the UIMenuController is emptied of menuItems. The solution, though hacky, is simple.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
NSString *selectorString = NSStringFromSelector(action);
BOOL isAccessibilitySelector = [selectorString isEqualToString:#"_accessibilitySpeak:"] || [selectorString isEqualToString:#"_accessibilityPauseSpeaking:"];
if (isAccessibilitySelector && [super canPerformAction:action withSender:sender]) {
//(re)add menuItems to UIMenuController
return YES;
}
return NO;
}
I should note that you must re-add the menuItems after their canPerformAction...() has been called.
I have submitted this as radar:12931434. Update: DUP'ed to 13060693.
Some of the UIMenuController items can be found in UIResponder.h in UIKit framework.
#interface NSObject(UIResponderStandardEditActions) // these methods are not implemented in NSObject
- (void)cut:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)copy:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)paste:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)select:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)selectAll:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)delete:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_2);
- (void)makeTextWritingDirectionLeftToRight:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);
- (void)makeTextWritingDirectionRightToLeft:(id)sender __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0);
#end
But there is no speak text option there. It turns out if you override "canPerformAction: WithSelector:", within a subclass of your UIWebView or UITextField as listed below, you will also get a listing of all of the actions sent to self including the UIMenuController options.
// Override
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
NSLog(#"%#",NSStringFromSelector(action));
//if you are customizing your menu, return NO except for your specific selectors
return YES;
}
You'll find several methods that may interest you, including _accessibilitySpeak: and _accessibilityPauseSpeaking: and _define: (please note these three selectors are iOS 5 only). The underscore means that they are private, so also keep in mind that you can't directly call them with the classic [class selector] syntax.
Remember, these are system menuItems, which means Apple will stick them in front of any menu items you add, often leaving your menu items in a second layer accessed by tapping the > arrow. If you want to control the order in which the items are display, and/or mix Apple's system items with your items, you will need to create custom menu items for these actions that call a method in your class like this:
- (void) myAppSpeak: (UIMenuController*) sender
{
[super performSelector:#selector(_accessibilitySpeak:)];
}
Keep in mind that these methods need to be implemented in a subclass of a class that implements these already, such as a sub class of UIWebView....not a subclass of UIWebViewController.
Then inside the controller, or wherever you build your UIMenuController, create the custom button that calls this method. Be sure if you are in a web view, you are referencing an object of type of your subclass, and not the generic webview. Otherwise, it won't work.
UIMenuItem *speakMenuItem = [[UIMenuItem alloc] initWithTitle:#"Speak" action:#selector(myAppSpeak:)];
[UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObjects:speakMenuItem, etc. etc., nil];
Even though you are adding it to the your menu items, it will not appear unless you return YES for the selector in your canPerformAction: WithSelector: in your subclass of your web view or text field. So feel free to add items here that may be circumstantial otherwise. You can use logic in your subclassed view to sort that out.

How to get selection text from UIWebView?

, Hello, everyone.
I'm developing my app which has a feature to post article from website.
This is a picture of UIWebview with UIMenuController.
It was possible to get event when user tap the button. but I can't find the way to get the text the user selected.
In UITextView case, it has 'selectedRange' property, so it is easy to get selection text.
UIMenuItem *facebookMenuItem = [[UIMenuItem alloc] initWithTitle:#"Facebook" action:#selector(facebookMenuItemTapped:)];
UIMenuItem *twitterMenuItem = [[UIMenuItem alloc] initWithTitle:#"Twitter" action:#selector(twitterMenuItemTapped:)];
[UIMenuController sharedMenuController].menuItems = [NSArray arrayWithObjects: facebookMenuItem, twitterMenuItem, nil];
[twitterMenuItem release];
[facebookMenuItem release];
I would like to get the selection text on UIWebView.
Does anybody have an idea or hint?
Thanks.
Or if you donʾt want to mess with Javascript you can just copy the selection to the pasteboard and then retrieve it by running:
[[UIApplication sharedApplication] sendAction:#selector(copy:) to:nil from:self forEvent:nil];
NSString *text = [UIPasteboard generalPasteboard].string;

How can I make UIActionSheet translucent when shown from a tab bar?

I am using a very simple UIActionSheet. Here is the code below:
UIActionSheet *editActionSheet = [[UIActionSheet alloc] initWithTitle:#"What do you like to do?"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Delete All Tasks"
otherButtonTitles:#"Arrange Task List", #"Mark All as Done", nil];
editActionSheet.actionSheetStyle = UIBarStyleBlackTranslucent;
[editActionSheet showFromTabBar:appDel.tabBarController.tabBar];
[editActionSheet release];
Although I set the action sheet style to translucent, it always appear opaque. I don't know why?
Thank you,
What I did in an app I'm creating was use [editActionSheet showInView:appDel.tabBarController.superview]; instead of [editActionSheet showFromTabBar:appDel.tabBarController.tabBar];. Accomplishes the same thing for all intents and purposes, and is much easier to implement than your answer. Just another way.
When an action sheet is shown from a tab bar it will always take on the appearance of the tab bar. You can't make it translucent in this case. I haven't tried subclassing UIActionSheet and overriding any of the color or drawing properties but that might be worth a shot.
I'd recommend changing the title of your question to reflect the actual question (e.g. How can I make UIActionSheet translucent when shown from a tab bar?)
XJones, finally, I managed to get the translucent action sheet!.
First, I hide the tab bar, then I show the translucent action sheet and immediatley after that show the tab bar. The finally code would be like that:
appDel.tabBarController.tabBar.hidden = YES;
NSString *controlBar;
if ([[settingsDictionary objectForKey:#"Task Control Bar"] isEqualToString:#"Hidden"]) {
controlBar = #"Show Task Control Bar";
} else {
controlBar = #"Hide Task Control Bar";
}
UIActionSheet *editActionSheet = [[UIActionSheet alloc] initWithTitle:#"What do you like to do?"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Delete All Tasks"
otherButtonTitles:#"Arrange Task List", #"Mark All as Done", controlBar, nil];
editActionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[editActionSheet showInView:self.tableView];
appDel.tabBarController.tabBar.hidden = NO;
[editActionSheet release];
You know what, I know now why Apple wanted this action sheet to be opaque. The translucent action sheet cancel button conflicts a little bit with the selected bar item (the blue one). It's not "so" noticed but I think an opaque one is a better solution.

Override iPhone copy menu captions on a long-press?

Is it possible to override the captions in the "Copy" menu when the iphone user long-presses on some text? Essentially, I'd like to change the text to something like "Create a Note" instead of "Copy". Is that possible?
You can add custom menus via UIMenuController's menuItems property, something like:
UIMenuItem* item1 = [[UIMenuItem alloc] initWithTitle:#"One" action:#selector(DoThingOne:)];
UIMenuItem* item2 = [[UIMenuItem alloc] initWithTitle:#"Two" action:#selector(DoThingTwo:)];
[UIMenuController sharedMenuController].menuItems = [[[NSArray alloc] initWithObjects:item1, item2, nil] autorelease];
[item1 release];
[item2 release];
However, this is only in iPhone OS 3.2, which would make it iPad only at this point. There's an example here (scroll down to "Custom Edit Menu Items").
As for altering the existing items, I do not believe that is possible currently.

How do I change the color of a Cocos2d MenuItem?

[MenuItemFont setFontSize:20];
[MenuItemFont setFontName:#"Helvetica"];
//I'm trying to change the color of start (below item)
MenuItem *start = [MenuItemFont itemFromString:#"Start Game"
target:self
selector:#selector(startGame:)];
MenuItem *help = [MenuItemFont itemFromString:#"Help"
target:self
selector:#selector(help:)];
Menu *startMenu = [Menu menuWithItems:start, help, nil];
[startMenu alignItemsVertically];
[self add:startMenu];
MenuItemFont *start = [MenuItemFont itemFromString:#"Start Game"
target:self
selector:#selector(startGame:)];
[start.label setRGB:0 :0 :0]; // Black menu item
Label is a property of MenuItemFont, a subclass of MenuItem, so you lose it during the implicit cast to MenuItem.
Alternatively, you could do:
[((MenuItemFont *)start).label setRGB:0 :0 :0]
(but that's ugly, and startMenu will take a MenuItemFont with no complaints).
Keep in mind that the colors are for the most part hardcoded in MenuItemFont, so calling 'setIsEnabled' will set the colors back to grey or white. This happens around line 239 of MenuItem.m if you need to tweak it. If I get around to making a patch to expose this functionality on MenuItemFont (assuming it's not already in the pre-.7.1 sources) I'll update my post.
setRGB has been set to setColor in newer versions. For example:
[start.label setColor: ccc3(200,0,200)];
You can change it like this (at least on Cocos2d version 0.99.5)
CCMenuItemFont *startMenuItem = [CCMenuItemFont itemFromString:#"Start" target:self selector:#selector(startTapped:)];
[startMenuItem setColor:ccBLACK];