我正在尝试使用以下代码:
UIMenuController * menu = [UIMenuController sharedMenuController];
[menu setTargetRect: CGRectMake(100, 100, 100, 100) inView: self.view];
[menu setMenuVisible: YES animated: YES];
菜单实例已准备就绪,但未显示 - 宽度始终为零。
或者这个UIPasteboard/UIMenuController
主题是否有一些示例代码?
答案 0 :(得分:49)
即使我读完你所有的答案,我也无法使它工作。我正在提供适用于所有人的现成代码。
假设我们有一个名为Controller的控制器类。您只需将以下代码粘贴到此控制器即可使菜单处于其视图中:
- (void)loadView {
[super loadView];
UILongPressGestureRecognizer *gr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.view addGestureRecognizer:gr];
}
- (void) longPress:(UILongPressGestureRecognizer *) gestureRecognizer {
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
CGPoint location = [gestureRecognizer locationInView:[gestureRecognizer view]];
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *resetMenuItem = [[UIMenuItem alloc] initWithTitle:@"Item" action:@selector(menuItemClicked:)];
NSAssert([self becomeFirstResponder], @"Sorry, UIMenuController will not work with %@ since it cannot become first responder", self);
[menuController setMenuItems:[NSArray arrayWithObject:resetMenuItem]];
[menuController setTargetRect:CGRectMake(location.x, location.y, 0.0f, 0.0f) inView:[gestureRecognizer view]];
[menuController setMenuVisible:YES animated:YES];
}
}
- (void) copy:(id) sender {
// called when copy clicked in menu
}
- (void) menuItemClicked:(id) sender {
// called when Item clicked in menu
}
- (BOOL) canPerformAction:(SEL)selector withSender:(id) sender {
if (selector == @selector(menuItemClicked:) || selector == @selector(copy:)) {
return YES;
}
return NO;
}
- (BOOL) canBecomeFirstResponder {
return YES;
}
为了使菜单工作,必须做的是firstResponder(在我们的例子中我们的控制器 - 见[self becomeFirstResponder]行)必须能够成为第一响应者(覆盖方法canBecomeFirstResponder导致默认实现返回NO )以及- (BOOL) canPerformAction:(SEL)selector withSender:(id) sender
应该对firstResponder
答案 1 :(得分:7)
如果您正在实现自定义视图并且该视图应该是响应者(而不是其他视图,如UITextField),则需要在视图中覆盖canBecomeFirstResponder函数并返回YES:
- (BOOL)canBecomeFirstResponder {
return YES;
}
然后,当您显示菜单时,您应该执行以下操作:
- (void)myMenuFunc {
if (![self becomeFirstResponder]) {
NSLog(@"couldn't become first responder");
return;
}
UIMenuController *theMenu = [UIMenuController sharedMenuController];
CGRect selectionRect = CGRectMake(0, 0, 0, 0);
[theMenu setTargetRect:selectionRect inView:self];
[theMenu setMenuVisible:YES animated:YES];
}
答案 2 :(得分:6)
如果有人仍然有问题:我的菜单曾经工作,有一天奇迹般地停止工作。我的应用程序中的其他所有内容仍然可用现在我已经从[window makeKeyAndVisible]
方法移除了application:didFinishLaunchingWithOptions:
方法,虽然其他一切仍然有用,但这会中断UIMenuController
!
我身边的愚蠢错误,很难找到罪魁祸首......
答案 3 :(得分:4)
要显示UIMenuController,必须添加以下内容
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(cut:))
return NO;
else if (action == @selector(copy:))
return YES;
else if (action == @selector(paste:))
return NO;
else if (action == @selector(select:) || action == @selector(selectAll:))
return NO;
else
return [super canPerformAction:action withSender:sender];
}
答案 4 :(得分:2)
我认为Cam是对的,需要覆盖canPerformAction和canBecomeFirstResponder
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(doSomething:)) {
return YES;
}
return NO;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
答案 5 :(得分:1)
// MyView.h
@interface MyView : UIView {
IBOutlet UITextField * textField_;
}
@end
// MyView.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"show menu");
[textField_ becomeFirstResponder];
// [self.window becomeFirstResponder];
UIMenuController * menu = [UIMenuController sharedMenuController];
[menu setTargetRect: CGRectMake(0, 0, 100, 10) inView: self];
[menu setMenuVisible: YES animated: YES];
NSLog(@"menu width %f, visible %d", menu.menuFrame.size.width, menu.menuVisible);
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
return YES;
}
您需要在canPerformAction中添加更多代码:withSender: - 它应该检查粘贴板和您的选择状态。 Apple的iPhone应用程序编程指南提供了几个代码片段。
答案 6 :(得分:0)
您不必将UIMenuController* menu
添加到主视图或子视图中,即E.G。 self.view
?
我认为它类似于[self.view addSubView:menu.view];
或者我错过了你的问题。您可能还想设置菜单视图的框架。
答案 7 :(得分:0)
UIMenuController没有视图。我刚从apple的iPhone Application Programming Guide: Event Handling搜索了一些代码:
清单3-4显示编辑菜单
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *theTouch = [touches anyObject]; if ([theTouch tapCount] == 2 && [self becomeFirstResponder]) { // selection management code goes here... // bring up editing menu. UIMenuController *theMenu = [UIMenuController sharedMenuController]; CGRect selectionRect = CGRectMake(currentSelection.x, currentSelection.y, SIDE, SIDE); [theMenu setTargetRect:selectionRect inView:self]; [theMenu setMenuVisible:YES animated:YES]; } }
答案 8 :(得分:0)
我是按照以下方式做到的。在init中经过很短的延迟后,只需调用显示菜单的方法。我不想从View Controller中调用它,也没有找到表示我的自定义视图出现的事件,我已准备好显示菜单。从我的角度来看,这样就行了。延迟可以更少,但由你决定。
@implementation DTSignatureImageView
- (id)initWithImage:(UIImage *)image
{
self = [super initWithImage:image];
if(self){
self.contentMode = UIViewContentModeScaleAspectFit;
self.frame = CGRectMake(0, 0, image.size.width / 2.5, image.size.height / 2.5);
self.userInteractionEnabled = YES;
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(signatureDidPan:)];
[self addGestureRecognizer:pan];
[self becomeFirstResponder];
[self performSelector:@selector(showMenu) withObject:nil afterDelay:0.5];
}
return self;
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (void)showMenu
{
UIMenuController *menu = [UIMenuController sharedMenuController];
menu.menuItems = @[
[[UIMenuItem alloc] initWithTitle:@"Apply" action:@selector(applySignature)],
[[UIMenuItem alloc] initWithTitle:@"Update" action:@selector(updateSignature)],
[[UIMenuItem alloc] initWithTitle:@"Clear" action:@selector(delegateSignature)]];
[menu setTargetRect:self.bounds inView:self];
[menu setMenuVisible:YES animated:YES];
}
- (NSArray *)menuActions
{
static NSArray *actions = nil;
if (actions == nil){
actions = @[
NSStringFromSelector(@selector(applySignature)),
NSStringFromSelector(@selector(updateSignature)),
NSStringFromSelector(@selector(delegateSignature))];
}
return actions;
}
- (void) signatureDidPan: (UIPanGestureRecognizer *)gesture
{
switch (gesture.state) {
case UIGestureRecognizerStateBegan: {
[[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];
break;
}
case UIGestureRecognizerStateEnded: {
[self becomeFirstResponder];
[self showMenu];
}
default:
break;
}
CGPoint point = [gesture locationInView:gesture.view.superview];
gesture.view.center = point;
}