2009-07-18 41 views
19

我試圖讓下面的代碼工作:如何讓UIMenuController爲自定義視圖工作?

UIMenuController * menu = [UIMenuController sharedMenuController]; 
[menu setTargetRect: CGRectMake(100, 100, 100, 100) inView: self.view]; 
[menu setMenuVisible: YES animated: YES]; 

菜單實例已準備就緒,但它並不顯示 - 寬度始終爲零。

或者是否有這UIPasteboard/UIMenuController主題上的一些示例代碼?

回答

0

難道你不需要將UIMenuController* menu添加到主或子視圖,E.G. self.view? 我認爲這就像[self.view addSubView:menu.view];或者我錯過了你的問題的重點。您可能還想設置菜單視圖的框架。

0

UIMenuController沒有視圖。我只是搜查從蘋果公司的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]; 
    } 
} 
+0

評論有字符數限制 - 所以我在這裏發佈代碼。 – 2009-07-18 07:19:10

+0

剛發現一個解決方法: 在視圖中放入一個隱形的UITextField,並使其成爲第一響應者。然後複製粘貼菜單將正確彈出。 – 2009-07-18 08:28:20

+0

我有這個相同的問題(我的自定義視圖是UITableViewCell的一個子類;但否則它是相同的情況)。一個無形的UITextField不幫助我。菜單仍然沒有顯示,menuFrame仍然是全零。此外,只要我將UITextField設置爲firstResponder,鍵盤就會彈出。你能爲你的解決方案發布一些示例代碼嗎? – 2009-07-18 16:08:18

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應用程序編程指南提供了幾個代碼片段。

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]; 
} 
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]; 
} 
+0

你能告訴我如何在此添加Forward選項嗎?我正在尋找它,所以幫助我..! – Vivek2012 2012-01-25 06:26:26

2

我覺得凸輪是正確的,需要同時覆蓋canPerformAction和canBecomeFirstResponder

- (BOOL) canPerformAction:(SEL)action withSender:(id)sender 
{ 
    if (action == @selector(doSomething:)) { 
     return YES; 
    } 
    return NO; 
} 

- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 
48

我是不是能夠得到,即使我讀了所有你的答案它的工作。我正在提供適用於所有人的現成代碼。

比方說,我們有一個名爲控制器控制器類。您可以將下面的代碼簡單地粘貼到該控制器具有菜單視圖工作:


- (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(在我們的例子中我們的控制器 - 看線與[自becomeFirstResponder])具有能夠成爲第一響應(重寫方法canBecomeFirstResponder原因默認實現否)以及- (BOOL) canPerformAction:(SEL)selector withSender:(id) sender應YES返回到可以由firstResponder

6

執行。在情況下有人仍然有任何動作問題:我的菜單曾經工作,有一天奇蹟般地停止工作。我應用程序中的其他內容仍然有效。現在我已經從application:didFinishLaunchingWithOptions:方法中刪除了[window makeKeyAndVisible]方法,而其他一切仍然有效,這會打破UIMenuController!在我身邊

愚蠢的錯誤,很難找到罪魁禍首......

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; 
} 
相關問題