iOS:弹出菜单的行为与第一响应者设置不符

时间:2011-01-14 16:43:12

标签: iphone objective-c cocoa-touch ios

我的应用程序中有几个继承UIView的对象正在跟踪它们上的点击并显示复制/粘贴弹出窗口(如果它们包含某些特定数据)。当弹出窗口时,我也改变了对象的外观。

这是如何实施的:

- (void)viewDidReceiveSingleTap:(NSNotification *)n {
    MyObject *mo = (MyObject *)n.object;

    [mo becomeFirstResponder];
    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu update];

    [menu setTargetRect:CGRectMake(...) inView:mo];

    [menu setMenuVisible:YES animated:YES];
}
反过来,

MyObject类将canBecomeFirstResponder:canResignFirstResponder:定义为始终返回YESbecomeFirstResponder:resignFirstResponder:canPerformAction:withSender:也相应地定义(这是我更改对象外观的地方)。

出现了问题:

我点按对象1.上面的方法viewDidReceiveSingleTap:被调用,对象的canBecomeFirstResponder:becomeFirstResponder:也被调用。弹出菜单按预期显示。

我点击另一个对象2.再次调用viewDidReceiveSingleTap:,这就是问题开始的地方。首先,对象1的canResignFirstResponder:resignFirstResponder:被调用,但并非总是如此,我无法弄清楚模式。对象2的canBecomeFirstResponder:becomeFirstResponder:被正确调用,但弹出菜单不会重定位。它只是消失了(虽然在viewDidReceiveSingleTap:我明确地称之为setMenuVisible:YES)。为了使它出现,我必须再次点击对象2(或任何其他) - 在这种情况下,我可以从调试器看到对象2被设置为第一响应者,它只是弹出窗口不是出现。

我做错了什么?关于弹出菜单可见性和第一响应者之间关系的任何线索?

1 个答案:

答案 0 :(得分:1)

问题在于,当您点击菜单上的任何地方时,它会自动隐藏动画。隐藏优先于你的动画节目。因此,如果您点按某个视图以显示菜单,请点按其他位置(在其他任意一个视图或其他任何位置),然后点按其中一个视图,菜单将每次显示。

我认为保留这种行为是一个很好的论据,因为它是用户期望的标准行为。但是,当然,您可以更好地了解对您的应用程序有意义的内容。所以,这就是诀窍:

[menu setMenuVisible:NO animated:NO];
[menu setMenuVisible:YES animated:YES];

以下是我用来试用的代码:

@implementation MenuView

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor blueColor];
    }
    return self;
}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [self becomeFirstResponder];
    UIMenuController *menu = [UIMenuController sharedMenuController];
    UIMenuItem *item = [UIMenuItem alloc] initWithTitle:@"Test"
                                                 action:@selector(test)];
    NSArray *items = [NSArray arrayWithObject:item];
    [item release];
    [menu setMenuItems:items];

    [menu setTargetRect:self.bounds inView:self];

    [menu setMenuVisible:NO animated:NO];
    [menu setMenuVisible:YES animated:YES];
}

- (void)test {
    NSLog(@"Test!");
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    return action == @selector(test);
}

- (BOOL)canBecomeFirstResponder {
    NSLog(@"Can become called");
    return YES;
}

- (BOOL)canResignFirstResponder {
    NSLog(@"Can resign called");
    return YES;
}

- (BOOL)becomeFirstResponder {
    [super becomeFirstResponder];
    NSLog(@"Become called");

    return YES;
}

- (void)dealloc {
    [super dealloc];
}


@end