2009-07-18 33 views
19

Tôi đang cố gắng để có được những công việc mã sau:Làm cách nào để UIMenuController hoạt động cho chế độ xem tùy chỉnh?

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

Các ví dụ đơn đã sẵn sàng nhưng nó không hiển thị - chiều rộng luôn là zero.

Hoặc có một số mã mẫu trên chủ đề UIPasteboard/UIMenuController này không?

Trả lời

0

Bạn không phải thêm UIMenuController* menu vào chính hoặc chế độ xem phụ, E.G. self.view? Tôi nghĩ rằng đó là một cái gì đó giống như [self.view addSubView:menu.view]; Hoặc tôi đang thiếu điểm của câu hỏi của bạn. Bạn cũng có thể muốn đặt khung của chế độ xem của trình đơn.

0

UIMenuController không có chế độ xem. Tôi chỉ tìm kiếm một số mã từ iPhone Application Programming Guide: Event Handling táo:

Liệt kê 3-4 Hiển thị các chỉnh sửa menu

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

nhận xét có giới hạn ký tự - vì vậy tôi đăng mã tại đây. –

+0

chỉ tìm thấy giải pháp thay thế: Đặt UITextField vô hình trong chế độ xem và đặt làm phản hồi đầu tiên. Sau đó, menu sao chép sẽ xuất hiện chính xác. –

+0

Tôi đang gặp vấn đề tương tự này (chế độ xem tùy chỉnh của tôi là lớp con của UITableViewCell; nhưng nếu không thì đó là tình huống tương tự). Một UITextField vô hình không giúp tôi. Menu vẫn không hiển thị và menuFrame vẫn là tất cả các số không. Ngoài ra, bàn phím bật lên bất cứ khi nào tôi làm cho UITextField trở thành một phiên bản đầu tiên. Bạn có thể đăng một số mã mẫu cho công việc của bạn không? –

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

Bạn cần phải thêm mã hơn trong canPerformAction: withSender: - nó nên kiểm tra các bảng và trạng thái lựa chọn của bạn. Hướng dẫn lập trình ứng dụng iPhone của Apple cung cấp một số đoạn mã.

7

Nếu bạn đang thực hiện một giao diện tùy chỉnh và xem đó là nghĩa vụ phải được sự trả lời (như trái ngược với một số quan điểm khác, giống như một UITextField), bạn cần phải ghi đè lên các chức năng canBecomeFirstResponder theo quan điểm của bạn và gửi lại YES:

- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 

sau đó, khi bạn đang hiển thị menu, bạn nên làm một cái gì đó như sau:

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

để hiển thị UIMenuController người ta phải thêm sau

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

u có thể cho tôi biết cách thêm tùy chọn Chuyển tiếp trong này không ?? Tôi đang tìm kiếm nó để giúp tôi trong đó ..! – Vivek2012

2

Tôi nghĩ Cam là đúng, cần ghi đè lên cả canPerformAction và canBecomeFirstResponder

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

- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 
48

tôi đã không thể có được nó làm việc ngay cả khi tôi đọc tất cả các câu trả lời của bạn. Tôi đang trình bày mã sẵn sàng sẽ hoạt động với mọi người.

Giả sử chúng tôi có lớp điều khiển có tên Bộ điều khiển. Bạn chỉ có thể dán đoạn mã sau để điều khiển này có menu làm việc trên quan điểm của mình:


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

gì đã được thực hiện để cho menu để làm việc là firstResponder (trong trường hợp của chúng tôi điều khiển của chúng tôi - xem dòng với [tự trở thànhFirstResponder]) phải có khả năng trở thành người trả lời đầu tiên (phương thức ghi đè canBecomeFirstResponder gây ra việc trả về mặc định NO) cũng như - (BOOL) canPerformAction:(SEL)selector withSender:(id) sender, nên trả lại CÓ cho bất kỳ hành động nào có thể được thực hiện bởi firstResponder

+5

Bạn có thể muốn thay đổi xác nhận đó để sử dụng canBecomeFirstResponder và đặt trở thànhFirstResponder bên ngoài xác nhận;) – antsyawn

+0

Điều này hoạt động hoàn hảo. Lúc đầu tôi hơi lo ngại rằng [tự trở thành FirstResponder] sẽ mang bàn phím lên, nhưng không. Cảm ơn bạn! –

+0

Trong phương thức sao chép, làm thế nào tôi có thể nhận được văn bản đã chọn? để sao chép vào UIPasteboard –

6

Trong trường hợp ai đó vẫn có vấn đề: Trình đơn của tôi được sử dụng để làm việc và một số ngày ngừng hoạt động một cách kỳ diệu. Mọi thứ khác trong ứng dụng của tôi vẫn hoạt động. Bây giờ tôi đã gỡ bỏ phương pháp [window makeKeyAndVisible] từ phương pháp application:didFinishLaunchingWithOptions: và trong khi mọi thứ khác vẫn hoạt động, điều này sẽ vi phạm UIMenuController!

Lỗi ngu ngốc ở bên cạnh tôi, khó tìm được thủ phạm ...

+1

Cảm ơn vì điều này. Hóa ra nó vui vẻ với tôi, không chắc chắn làm thế nào dòng makeKeyAndVisible đã được gỡ bỏ nhưng không có nó tôi gần như phá hủy màn hình của tôi và sử dụng các cạnh sắc nét của nó để cam kết Hari-Kari. –

+1

Cảm ơn bạn rất nhiều. Tôi đã trình bày một loupe trong cửa sổ riêng của mình, và cần thiết để làm cho phím cửa sổ chính một lần nữa cho UIMenuController để làm việc. – hatfinch

0

Tôi đã thực hiện theo cách sau. Chỉ cần gọi phương thức hiển thị menu sau khi hết thời gian trễ trong init. Tôi không muốn gọi nó từ View Controller và cũng không tìm thấy một sự kiện cho biết rằng chế độ xem tùy chỉnh của tôi đã xuất hiện và tôi đã sẵn sàng hiển thị menu. Vì vậy, cách này OK từ quan điểm của tôi. Chậm trễ có thể ít hơn, nhưng tùy thuộc vào bạn.

@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; 
} 
Các vấn đề liên quan