2009-07-18 8 views
19

Ich versuche, die folgenden Code Arbeit zu bekommen:Wie funktioniert UIMenuController für eine benutzerdefinierte Ansicht?

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

Das Menü Instanz ist bereit, aber es zeigt nicht, - die Breite immer Null ist.

Oder gibt es einen Beispielcode zu diesem Thema UIPasteboard/UIMenuController?

Antwort

0

Sie müssen die UIMenuController* menu nicht zu der Haupt- oder Unteransicht hinzufügen, E.G. self.view? Ich denke, es ist so etwas wie [self.view addSubView:menu.view]; Oder fehlt mir der Punkt Ihrer Frage. Sie können auch den Rahmen der Menüansicht festlegen.

0

UIMenuController hat keine Ansicht. Ich suchte nur einen Code aus Apfel iPhone Application Programming Guide: Event Handling:

Eintrag 3-4 das Bearbeitungsmenü

- (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

der Kommentar hat die Zeichen Grenze - also poste ich den Code hier. –

+0

hat gerade eine Problemumgehung gefunden: Setzen Sie ein unsichtbares UITextField in die Ansicht und machen Sie es zum Ersthelfer. Dann wird das Kopieren-Einfügen-Menü korrekt angezeigt. –

+0

Ich habe das gleiche Problem (meine benutzerdefinierte Ansicht ist eine Unterklasse von UITableViewCell; aber ansonsten ist es die gleiche Situation). Ein unsichtbares UITextField hilft mir nicht. Das Menü wird immer noch nicht angezeigt, und der menuFrame ist immer noch nur Nullen. Außerdem erscheint die Tastatur immer dann, wenn ich das UITextField zu einem FirstResponder mache. Können Sie einen Beispielcode für Ihre Problemumgehung posten? –

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; 
} 

Sie benötigen angezeigte mehr Code in canPerformAction hinzuzufügen: withSender: - es sollte überprüfen die Pasteboard und Ihren Auswahlstatus. Apples iPhone Application Programming Guide bietet mehrere Code-Snippets.

7

Wenn Sie die Implementierung einer benutzerdefinierten Ansicht und die Ansicht soll der Responder sein (im Gegensatz zu einer anderen Ansicht gegenüber, wie ein UITextField), müssen Sie die canBecomeFirstResponder Funktion Ihrer Ansicht nach außer Kraft zu setzen und das Rück YES:

- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 

dann, wenn Sie das Menü sind anzeigen, sollten Sie etwas wie folgt tun:

- (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 ein angezeigt hat folgende hinzufügen

- (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

können Sie mir sagen, wie Forward Option in diesem hinzuzufügen? Ich suche es so hilf mir dabei ..! – Vivek2012

2

Ich denke, Cam richtig ist, müssen beide canPerformAction und canBecomeFirstResponder

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

- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 
48

ich nicht in der Lage außer Kraft gesetzt war es sogar zum Laufen zu bringen, wenn ich alle Ihre Antworten lesen. Ich präsentiere Code, der für alle funktioniert.

Nehmen wir an, wir haben eine Controller-Klasse namens Controller. Sie können einfach den folgenden Code zu diesem Controller fügen das Menü auf seiner Ansicht zu arbeiten haben:


- (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; 
} 

Was, um das Menü zu arbeiten, dass der firstResponder (in unserem Fall unserer Controller ist getan werden muss - siehe Zeile mit [self becomeFirstResponder]) Ersthelfer (Override-Methode canBecomeFirstResponder Ursache Standardimplementierung gibt NO) als - (BOOL) canPerformAction:(SEL)selector withSender:(id) sender als auch werden können, hat, die ja auf eine Aktion zurückkehren soll, die noch von firstResponder

+5

Sie könnten diese Behauptung ändern, um canBecomeFirstResponder zu verwenden und den findFirstResponder außerhalb der Assert zu setzen;) – antsyawn

+0

Dies funktioniert perfekt. Ich war anfangs etwas besorgt, dass [self wirdFirstResponder] die Tastatur hochbringen wird, aber das tat es nicht. Vielen Dank! –

+0

Wie kann ich den ausgewählten Text in der Kopiermethode erhalten? auf das UIPasterboard kopieren –

6

falls jemand durchgeführt werden können, hat Probleme: Mein Menü arbeitete früher und eines Tages hörte auf wundersame Weise auf zu arbeiten. Alles andere in meiner App funktionierte noch. Jetzt hatte ich die [window makeKeyAndVisible] Methode von application:didFinishLaunchingWithOptions: Methode entfernt, und während alles andere noch funktionierte, bricht das UIMenuController!

dumme Fehler auf meiner Seite, schwierig, die Täter zu finden ...

+1

Vielen Dank dafür. Es stellte sich heraus, dass es mir passiert ist, nicht sicher, wie die makeKeyAndVisible-Linie entfernt wurde, aber ohne sie hätte ich fast meinen Monitor zerstört und seine scharfen Kanten benutzt, um Hari-Kari zu begehen. –

+1

Vielen Dank. Ich präsentierte eine Lupe in einem eigenen Fenster und musste den Hauptfensterschlüssel erneut eingeben, damit UIMenuController funktionierte. – hatfinch

0

Ich habe es in der folgenden Art und Weise unten. Rufen Sie einfach die Methode auf, die das Menü nach sehr kurzer Verzögerung in Init zeigt. Ich wollte es nicht über View Controller aufrufen und habe auch kein Ereignis gefunden, das anzeigt, dass meine benutzerdefinierte Ansicht angezeigt wurde und ich bereit bin, das Menü anzuzeigen. Also aus meiner Sicht ok. Verzögerung kann weniger sein, aber es liegt an Ihnen.

@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; 
} 
Verwandte Themen