views:

662

answers:

1

I have a UITextView placed just below a view containing an ad and when the user tries to paste in text the paste menu overlays the ad which is just above the insertion point. I don't want to encourage accidental clicks so I'm looking for a way to make the menu display below the insertion point instead of above it. Or maybe there's a way to trick the menu controller into thinking that text view is already at the top of the screen.

I've tried using the setTargetRect:inView: method on the sharedMenuController but that has no effect. Apparently the text view doesn't use the shared menu controller.

I've tried adding variations of the following line to my view controller's textViewDidBeginEditing:textView and viewDidLoad methods with no luck.

[[UIMenuController sharedMenuController] setTargetRect: CGRectMake(140, 120, 5, 5) inView:self.view];

+2  A: 

The short answer is, you can't do this. You can sometimes, but not very reliably. The problem is that "UITextView is a pretty special case, and subclassing it for the purposes of handling touches is really not possible in iPhone OS 3.0."*

The way around this would be to subclass UIWindow and override its sendEvent method so it sets your menu's target rect and then displays the menu.

        UIMenuController *menu = [UIMenuController sharedMenuController]; 
        CGRect selectionRect = CGRectMake(0, 0, 270, 100); 
        [theMenu setTargetRect:selectionRect inView:theTextView.superview]; 
        [menu setMenuVisible:YES animated:YES];

However, there are 4 ways to bring up an edit menu and this only works in the case where the menu is triggered directly by a touch event. In the other cases the menu is created indirectly as the result of touching another ui element (like, select or copy menu items, or touching a blue selection dot).

Since I can't reliably control the location of the menu, I decided to listen for hide and show notifications and toggle user interaction for my ad view. But that doesn't work either since those notifications only trigger if the menu was displayed as a result of you executing setMenuVisible.

If the user presses in the UITextView and holds, This brings up a round magnifying glass. When the touch ends, a menu appears. For these menus and their children, as far as I can tell, its impossible to set their targetRect or to get notifications from them. I give up.

I filed an enhancement request with Apple. Hopefully they'll change this in a future version of the OS.

Dawn