2009-10-22 3 views
6

Xin chào, tôi muốn tạo một menu bong bóng tùy chỉnh, như menu cắt/sao chép/dán, trong IPhone SDK3.x. Tôi biết đó là UIMenuController nhưng nó chỉ cung cấp menu cắt/sao chép/quá khứ chuẩn. Bất cứ ai cũng biết cách tạo một menu bong bóng tương tự như thế này. Bất kỳ ví dụ và mã để tham khảo?Tùy chỉnh UIMenuController

Trả lời

-1

Sử dụng trình đơn Thuộc tínhItems trên UIMenuController.

+0

Nói chung, câu trả lời hữu ích hơn nhiều nếu chúng bao gồm giải thích mã được dự định làm gì và tại sao giải quyết vấn đề mà không giới thiệu người khác –

39

1) bạn cần phải thêm các mục menu tùy chỉnh để các UIMenuController chia sẻ:

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) bạn cần phải thực hiện các phương pháp xử lý của bạn ở đâu đó trong chuỗi trả lời cho quan điểm cho rằng sẽ là người đầu tiên trả lời khi khi bạn hiển thị menu:

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

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

3) bạn tùy chọn cần phải thực hiện canPerformAction: trong chuỗi trả lời cho quan điểm cho rằng sẽ là người đầu tiên trả lời khi khi bạn hiển thị 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) nếu chế độ xem bạn muốn trình bày trình đơn chưa hỗ trợ hiển thị menu, (tức là một UIWebView sẽ hiển thị một trình đơn khi người dùng thực hiện một cú nhấn, nhưng một UILabel không có hỗ trợ để hiển thị một menu), thì bạn cần tự trình bày trình đơn đó. Điều này thường được thực hiện bằng cách gắn một UILongPressGestureRecognizer để xem, sau đó hiển thị menu trong callback:

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

Lưu ý, phải có một quan điểm cho rằng tuyên bố firstResponder cho menu để hiển thị.

5) đảm bảo chế độ xem bạn đang hiển thị menu để trả về CÓ/TRUE thành canBecomeFirstResponder. Ví dụ, nếu bạn cố gắng tạo một UILabel một đáp ứng đầu tiên, nó sẽ trả về NO, vì vậy bạn sẽ phải phân lớp nó lại.

6) đó là về nó. Bạn có thể muốn từ chứcFirstResponder khi gọi lại hành động được gọi - nhưng để làm điều này, bạn sẽ cần phải thực hiện logic để khám phá firstResponder.

+0

người gửi trong canPerformAction không đại diện cho đối tượng nơi menu xuất hiện trong/bật (trong trường hợp của tôi một textview) - bất kỳ ý tưởng về lý do tại sao? – amok

+0

Được trả lời, tốt lắm! – gigahari

+0

'- [FirstViewController handleGesture ::]: bộ chọn không nhận dạng được gửi tới ví dụ 0x1e865800' cho phần tử được tập trung trên trang web. Làm thế nào để giải quyết vấn đề này? Khi không có phần tử bên trong trang nào được tập trung vào văn bản đầu vào thì phương thức này thực sự hoạt động. – Dmitry