Development Tip

UIMenuController가 표시되지 않음

yourdevel 2020. 12. 9. 21:50
반응형

UIMenuController가 표시되지 않음


사용자 지정 UIMenuController를 만들고 내보기에 표시하려고합니다. 내 코드는 다음과 같습니다.

UIMenuController *menuController = [UIMenuController sharedMenuController];
    UIMenuItem *listMenuItem = [[UIMenuItem alloc] initWithTitle:@"List" action:@selector(addList:)];

    [menuController setMenuItems:[NSArray arrayWithObject:listMenuItem]];
    [menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
    [menuController setMenuVisible:YES animated:YES];

    [listMenuItem release];

오류나 예외는 없지만 메뉴 컨트롤러는 표시되지 않습니다.


다음 세 가지를 수행해야합니다.

  1. -becomeFirstResponder뷰 또는 뷰 컨트롤러 를 호출해야합니다 .
  2. 보기 또는보기 컨트롤러를 구현해야합니다 -canBecomeFirstResponder(을 반환 YES).
  3. 선택적으로보기 또는보기 컨트롤러를 구현 -canPerformAction:action withSender:sender하여 개별적으로 메뉴 항목을 표시 / 숨길 수 있습니다 .

대답에는 세 가지가 언급되어 있지만 까다롭게 말하면 여섯 가지가 있습니다.

  1. 메뉴 핸들러는 UIView 여야합니다. 그렇지 않으면 -becomeFirstResponder실패합니다.
  2. 메뉴 핸들러는 userInteractionEnabled = YES
  3. 메뉴 핸들러는 뷰 계층 구조에 -window있어야하며 해당 속성은 inView:인수 의 뷰 창과 동일해야합니다 .
  4. 을 구현 -canBecomeFirstResponder하고 반환 해야합니다 YES.
  5. 당신은 호출 할 필요가 [handler becomeFirstResponder], [menu setTargetRect:inView:] 라고, 또는 후자는 실패합니다.
  6. 당신은 호출 할 필요가 [menu setTargetRect:inView](적어도 한 번)와 [menu setMenuVisible:animated:].

특히 위의 1-3 점이 나를 얻었습니다. 처음에는 사용자 정의 메뉴 처리기 클래스를 원했는데 UIResponder이로 인해 -becomeFirstResponder반환되었습니다 NO. 다음은이었다 UIView실패한 후, 나는 그것을 만드는 시도, UIButton하지만, 일을하는 만 때문에 userInteractionEnabled기본값 YES버튼과 NO대한 UIView의.


UIMenuController 보기가 첫 번째 응답자이고

- (BOOL)canPerformAction 메서드 반환 YES

따라서 메뉴 컨트롤러가 버튼 클릭시 표시되는 경우 버튼 동작의 첫 번째 줄은이어야합니다 [self becomeFirstResponder]. 참고 : 여기 self는 메뉴를 표시 할보기입니다.

메뉴가 길게 누르기 제스처에 표시되는 UIView경우 쓰기 전에 및 길게 누르기 이벤트에 longPressGesture를 추가합니다.

[menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
[menuController setMenuVisible:YES animated:YES];

쓰다 [self becomeFirstResponder];

그런 다음 OZ에서 언급 한 단계를 따릅니다.


아래는 전체 주석 처리 된 작업 예입니다.

서브 클래스 헤더 파일보기

#import <Foundation/Foundation.h>

@interface MenuControllerSupportingView : UIView
{

}
@end

서브 클래스 소스 파일보기

#import "MenuControllerSupportingView.h"

@implementation MenuControllerSupportingView

//It's mandatory and it has to return YES then only u can show menu items..
-(BOOL)canBecomeFirstResponder
{
  return YES;
}

-(void)MenuItemAClicked
{
  NSLog(@"Menu item A clicked");
}

-(void)MenuItemBClicked
{
 NSLog(@"Menu item B clicked");
}

-(void)MenuItemCClicked
{
  NSLog(@"Menu item C clicked");
}

//It's not mandatory for custom menu items

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

컨트롤러 헤더 파일보기

#import <UIKit/UIKit.h>

@interface ViewController1 : UIViewController

@end

컨트롤러 소스 파일보기

 #import "ViewController1.h"
 #import "MenuControllerSupportingView.h"

@interface ViewController1 ()
{
 MenuControllerSupportingView *vu;
}
@end

@implementation ViewController1

 - (void)viewDidLoad
{
  [super viewDidLoad];

  vu=[[SGGI_MenuControllerSupportingView alloc]initWithFrame:CGRectMake(0,0,768,1024)];

[self.view addSubview:vu];

 UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];

 [btn setFrame:CGRectMake(200,200,200,30)];

 [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];

 [btn setTitle:@"Show" forState:UIControlStateNormal];

 [btn addTarget:self action:@selector(SHowMenu) forControlEvents:UIControlEventTouchUpInside];

 [vu addSubview:btn];

}

-(void)SHowMenu
{
 UIMenuController *menucontroller=[UIMenuController sharedMenuController];

UIMenuItem *MenuitemA=[[UIMenuItem alloc] initWithTitle:@"A" action:@selector(MenuItemAClicked)];

UIMenuItem *MenuitemB=[[UIMenuItem alloc] initWithTitle:@"B" action:@selector(MenuItemBClicked)];

UIMenuItem *MenuitemC=[[UIMenuItem alloc] initWithTitle:@"C" action:@selector(MenuItemCClicked)];

[menucontroller setMenuItems:[NSArray arrayWithObjects:MenuitemA,MenuitemB,MenuitemC,nil]];

    //It's mandatory
[vu becomeFirstResponder];

    //It's also mandatory ...remeber we've added a mehod on view class
if([vu canBecomeFirstResponder])
{

    [menucontroller setTargetRect:CGRectMake(10,10, 0, 200) inView:vu];

    [menucontroller setMenuVisible:YES animated:YES];
}

}




-(void)didReceiveMemoryWarning
{
  [super didReceiveMemoryWarning];

}

@end

View 클래스에서 canPerformAction 에서 YES 만 반환 하면 카메라 기호, 잘라 내기, 복사 등과 같은 모든 기본 메뉴 항목이 표시됩니다.

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
 return YES;
}

카메라 만 보여주고 싶다면

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

}

모든 행동에 대해 알고 싶다면

링크를 방문하십시오


Just in case anyone is having this issue specifically (and randomly) with iOS6: you might want to look at this SO related to having Speak Selection enabled on the device (Settings -> General -> Accessibility -> Speak Selection: On). A small number of my users were not able to see the custom UIMenuItems and this was the cause.


In Swift 3.0 -

In my case I wanted to have the VC pre-select the text in a TextView and display a custom menu for the user to take action on that selection. As mentioned by Kalle, order is very important, especially making setMenuVisible last.

In VC, viewDidLoad:

menuCont = UIMenuController.shared
let menuItem1: UIMenuItem = UIMenuItem(title: "Text", action: #selector(rtfView.textItem(_:)))
let menuItems: NSArray = [menuItem1]
menuCont.menuItems = menuItems as? [UIMenuItem]

In VC, when the user hits a button:

@IBAction func pressed(_ sender: Any) {
    self.textView.selectedRange = NSMakeRange(rangeStart, rangeLength)
    self.textView.becomeFirstResponder()
    menuCont.setTargetRect(CGRect.zero, in: self.textView)
    menuCont.setMenuVisible(true, animated: true)
}

Finally, in the sub-class of the TextView:

class rtfView: UITextView {

override var canBecomeFirstResponder: Bool {
    return true
}

override func canPerformAction(_ action: Selector, withSender sender: Any!) -> Bool {
    if (action == #selector(textItem(_:))) {
        return true
    } else {
        return false
    }
  }
}

maybe because CGRectMake(50.0, 50.0, 0, 0) creates a CGRect with width = 0 and height = 0?

cheers, anka

참고URL : https://stackoverflow.com/questions/3112925/uimenucontroller-not-showing-up

반응형