我的应用程序中有几个继承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:
定义为始终返回YES
。 becomeFirstResponder:
,resignFirstResponder:
和canPerformAction:withSender:
也相应地定义(这是我更改对象外观的地方)。
出现了问题:
我点按对象1.上面的方法viewDidReceiveSingleTap:
被调用,对象的canBecomeFirstResponder:
和becomeFirstResponder:
也被调用。弹出菜单按预期显示。
我点击另一个对象2.再次调用viewDidReceiveSingleTap:
,这就是问题开始的地方。首先,对象1的canResignFirstResponder:
,resignFirstResponder:
被调用,但并非总是如此,我无法弄清楚模式。对象2的canBecomeFirstResponder:
和becomeFirstResponder:
被正确调用,但弹出菜单不会重定位。它只是消失了(虽然在viewDidReceiveSingleTap:
我明确地称之为setMenuVisible:YES
)。为了使它出现,我必须再次点击对象2(或任何其他) - 在这种情况下,我可以从调试器看到对象2被设置为第一响应者,它只是弹出窗口不是出现。
我做错了什么?关于弹出菜单可见性和第一响应者之间关系的任何线索?
答案 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