2009-10-22 15 views
6

Witam Chcę utworzyć niestandardowe menu bąbelkowe, takie jak menu wytnij/kopiuj/wklej, w pakiecie IPhone SDK3.x. Wiem, że to UIMenuController, ale zapewnia tylko standardowe menu cut/copy/minione. Każdy wie, jak zrobić menu bańki podobne do tego. Dowolny przykład i kod referencyjny?Dostosuj moduł UIMenuController

Odpowiedz

-1

Użyj właściwości menuItems na UIMenuController.

+0

Ogólnie odpowiedzi są o wiele bardziej pomocne, jeśli zawierają wyjaśnienie, co kod ma zamiar zrobić, i dlaczego to rozwiązuje problem bez wprowadzania innych. –

39

1) trzeba dodać elementy menu zwyczaj wspólnego UIMenuController:

UIMenuItem* miCustom1 = [[[UIMenuItem alloc] initWithTitle: @"Custom 1" action:@selector(onCustom1:)] autorelease]; 
UIMenuItem* miCustom2 = [[[UIMenuItem alloc] initWithTitle: @"Custom 2" action:@selector(onCustom2:)] autorelease]; 
UIMenuController* mc = [UIMenuController sharedMenuController]; 
mc.menuItems = [NSArray arrayWithObjects: miCustom1, miCustom2, nil]; 

2) trzeba realizować swoich metod obsługi gdzieś w łańcuchu reagujących na widok, który będzie pierwszym odpowiadające na kiedy wyświetlić menu:

- (void) onCustom1: (UIMenuController*) sender 
{ 
} 

- (void) onCustom2: (UIMenuController*) sender 
{ 
} 

3) opcjonalnie potrzeba wdrożenia canPerformAction: w łańcuchu reagujących na widoku, który będzie pierwszym odpowiadające na kiedy wyświetlić menu:

- (BOOL) canPerformAction:(SEL)action withSender:(id)sender 
{ 
    if (action == @selector(onCustom1:)) 
    { 
      return YES; // logic here for context menu show/hide 
    } 

    if (action == @selector(onCustom2:)) 
    { 
      return NO; // logic here for context menu show/hide 
    } 

    if (action == @selector(copy:)) 
    { 
      // turn off copy: if you like: 
     return NO; 
    } 

    return [super canPerformAction: action withSender: sender]; 
} 

4) jeśli widok, który chcesz wyświetlić, menu nie obsługuje już wyświetlania menu (tj. UIWebView wyświetli menu, gdy użytkownik wykona długie naciśnięcie, ale UILabel nie ma wbudowanej obsługi wyświetlania menu), a następnie musisz przedstawić menu samodzielnie. Często jest to zrobić poprzez dołączenie UILongPressGestureRecognizer do widoku, a następnie pokazano menu w zwrotnego:

UILongPressGestureRecognizer* gr = [[[UILongPressGestureRecognizer alloc] initWithTarget: self action: @selector(onShowMenu:) ] autorelease]; 
    [_myview addGestureRecognizer: gr]; 



- (void) onShowMenu: (UIGestureRecognizer*) sender 
{ 
    [sender.view becomeFirstResponder]; 

    UIMenuController* mc = [UIMenuController sharedMenuController]; 

    CGRect bounds = sender.view.bounds; 

    [mc setTargetRect: sender.view.frame inView: sender.view.superview]; 
    [mc setMenuVisible: YES animated: YES]; 
} 

Uwaga, nie musi być pogląd, że twierdzi firstResponder do menu, aby pokazać.

5) upewnij się, że widok pokazuje menu dla zwrotu TAK/PRAWDA do canBecomeFirstResponder. Na przykład, jeśli spróbujesz uczynić UILabel pierwszą odpowiedzią, zwróci ona NIE, więc będziesz musiał ją podklasować.

6) o to chodzi. Możesz chcieć zrezygnowaćFirstResponder po wywołaniu callback działania - ale aby to zrobić, musisz zaimplementować logikę, aby odkryć firstResponder.

+0

Nadawca w canPerformAction nie reprezentuje obiektu, w którym menu pojawia się w/na (w moim przypadku tekst) - jakiekolwiek pojęcie dlaczego? – amok

+0

Dobrze odpowiedział, dobra robota! – gigahari

+0

'- [FirstViewController handleGesture ::]: nierozpoznany selektor wysłany do instancji 0x1e865800' dla skoncentrowanego elementu na stronie. Jak naprawić ten problem? Kiedy żaden element wewnątrz strony nie jest skoncentrowany na wprowadzaniu tekstu, ta metoda naprawdę działa. – Dmitry