Summary: All I am trying to do is to have a UIControl subclass that shows a UIMenu when pressed and I have read this 100 but I am running into a crash when setting the contextMenuinteractionEnabled property to YES.

Similar question: 100


我有一个UIControl子类,我想要向它添加一个菜单,以便在单击控件时显示UIMenu.但是,在将contextMenuInteractionEnabled属性设置为yes时,我一直收到错误.

下面是控件子类:

@interface MyControl : UIControl
@end

@implementation MyControl
@end

它只是一个普通的UIControl子类.然后,我创建了该类的一个实例,并将contextMenuInteractionEnabled值设置为yes,如下所示:

MyControl *myControl = [[MyControl alloc] init];
myControl.contextMenuInteractionEnabled = YES; //<-- Thread 1: "Invalid parameter not satisfying: interaction"

但随后在运行此程序时,我收到以下错误消息:

错误消息

*-[我的控件添加交互:]中的断言失败,UIview.m:17965

*因未捕获异常‘NSInternalInconsistencyException’终止APP,原因:‘无效参数不满意:交互’

错误:NSInternalInconsistencyException

原因:无效参数不满意:交互

堆栈跟踪: (

0核心基础0x00000001b8181e94 5CDC5D9A-E506-3740-B64E-BB30867B4F1B+40596

1 libobjc.A.dylib 0x00000001b14b78d8 objc_EXCEPTION_SHORT+60

2基础0x00000001b2aa5b4c C431ACB6-FE04-3D28-B677-4DE6E1C7D81F+5528396

3 UIKitCore 0x00000001ba47e5bc 179501B6-0FC2-344A-B969-B4E3961EBE10+1349052

4 UIKitCore 0x00000001ba47ea70 179501B6-0FC2-344A-B969-B4E3961EBE10+1350256

)

Libc++abi:使用类型为NSException的未捕获异常终止

*因未捕获异常‘NSInternalInconsistencyException’终止APP,原因:‘无效参数不满意:交互’ terminating with uncaught exception of type NSException


问题

  1. 错误消息"INVALID PARAMETER NOT SINSING:Interaction"是什么意思?"互动"从何而来?如何解决?

  2. 我做错了什么?我想要的只是一个定制的UIControl,它可以在按下时显示菜单.就这样.

另外,这段代码对于UIButton实例来说工作得很好,所以UIButton类在内部做了一些我没有做的事情,但我不知道是什么.

Update 1

根据@DonMag的回答,我try 了一下:

    MyControl *control = [[MyControl alloc] init];
    control.showsMenuAsPrimaryAction = YES;

    UIContextMenuInteraction *contextMenuInteraction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
    [control addInteraction:contextMenuInteraction];

    [self.view addSubview:control];

它不再崩溃,如果我长时间按它,菜单甚至会显示出来.但我希望它能像常规菜单一样显示出来,作为按下该控件的主要操作.我想要做的是模仿UIButton上的menu套房产.这将是最理想的事情,如果我可以实现一个具有Menu属性的控件,然后使该菜单作为主要操作可用.

推荐答案

没有必要拨打.contextMenuInteractionEnabled = YES;...

下面是一个快速、完整的例子:

#import <UIKit/UIKit.h>

@interface MyControl : UIControl
@end

@implementation MyControl
@end

@interface ControlMenuViewController : UIViewController <UIContextMenuInteractionDelegate>
@end

@interface ControlMenuViewController ()
@end

@implementation ControlMenuViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    MyControl *myControl = [MyControl new];

    UIContextMenuInteraction *interaction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
    [myControl addInteraction:interaction];
    
    myControl.frame = CGRectMake(100, 200, 200, 50);
    myControl.backgroundColor = UIColor.systemRedColor;
    [self.view addSubview:myControl];
    
}

- (nullable UIContextMenuConfiguration *)contextMenuInteraction:(nonnull UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location {
    
    UIContextMenuConfiguration* config = [UIContextMenuConfiguration configurationWithIdentifier:nil
                                                                                 previewProvider:nil
                                                                                  actionProvider:^UIMenu* _Nullable(NSArray<UIMenuElement*>* _Nonnull suggestedActions) {
        
        NSMutableArray* actions = [[NSMutableArray alloc] init];
        
        [actions addObject:[UIAction actionWithTitle:@"Stand!" image:[UIImage systemImageNamed:@"figure.stand"] identifier:nil handler:^(__kindof UIAction* _Nonnull action) {
            NSLog(@"Stand!");
            //[self performMenuCommandStand];
        }]];
        [actions addObject:[UIAction actionWithTitle:@"Walk!" image:[UIImage systemImageNamed:@"figure.walk"] identifier:nil handler:^(__kindof UIAction* _Nonnull action) {
            NSLog(@"Walk!");
            //[self performMenuCommandWalk];
        }]];
        [actions addObject:[UIAction actionWithTitle:@"Run!" image:[UIImage systemImageNamed:@"figure.run"] identifier:nil handler:^(__kindof UIAction* _Nonnull action) {
            NSLog(@"Run!");
            //[self performMenuCommandRun];
        }]];
        
        UIMenu* menu = [UIMenu menuWithTitle:@"" children:actions];
        return menu;
        
    }];
    
    return config;

}

@end

Edit

略微修改以允许单击(主要操作):

#import <UIKit/UIKit.h>

@interface MyControl : UIControl
@property (strong, nonatomic) UIContextMenuConfiguration *menuCfg;
@end

@implementation MyControl
- (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location {
    return self.menuCfg;
}
@end

@interface ControlMenuViewController : UIViewController
@end

@interface ControlMenuViewController ()
@end

@implementation ControlMenuViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    MyControl *myControl = [MyControl new];
    
    myControl.frame = CGRectMake(100, 200, 200, 50);
    myControl.backgroundColor = UIColor.systemRedColor;
    [self.view addSubview:myControl];

    // menu configuration
    UIContextMenuConfiguration* config = [UIContextMenuConfiguration configurationWithIdentifier:nil
                                                                                 previewProvider:nil
                                                                                  actionProvider:^UIMenu* _Nullable(NSArray<UIMenuElement*>* _Nonnull suggestedActions) {
        
        NSMutableArray* actions = [[NSMutableArray alloc] init];
        
        [actions addObject:[UIAction actionWithTitle:@"Stand!" image:[UIImage systemImageNamed:@"figure.stand"] identifier:nil handler:^(__kindof UIAction* _Nonnull action) {
            NSLog(@"Stand!");
            //[self performMenuCommandStand];
        }]];
        [actions addObject:[UIAction actionWithTitle:@"Walk!" image:[UIImage systemImageNamed:@"figure.walk"] identifier:nil handler:^(__kindof UIAction* _Nonnull action) {
            NSLog(@"Walk!");
            //[self performMenuCommandWalk];
        }]];
        [actions addObject:[UIAction actionWithTitle:@"Run!" image:[UIImage systemImageNamed:@"figure.run"] identifier:nil handler:^(__kindof UIAction* _Nonnull action) {
            NSLog(@"Run!");
            //[self performMenuCommandRun];
        }]];
        
        UIMenu* menu = [UIMenu menuWithTitle:@"" children:actions];
        return menu;
        
    }];

    // set custom control menu configuration
    myControl.menuCfg = config;
    
    // show menu on single-tap (instead of long-press)
    [myControl setContextMenuInteractionEnabled:YES];
    myControl.showsMenuAsPrimaryAction = YES;
    
}

@end

Ios相关问答推荐

使用UIGraphicsBeginIMAext创建新图像会扭曲图像 colored颜色

设置堆栈视图的所有属性

preferredCompactColumn作为NavigationSplitViewColumn.sidebar传递,但仍能在iOS上看到详细信息页面

如何在SwiftUI中拥有基于操作系统版本的条件修饰符?

SwiftUI绑定到特定的一个或多个枚举 case

以编程方式更改VC&39;S导航栏按钮的属性,以响应另一个VC中的按钮按下

如何在SwiftUI中顺时针和逆时针两个方向应用旋转效果?

如果没有等待,SWIFT Async让任务抛出取消异常

如何在SwiftUI中基于嵌套视图中的状态动态显示外部视图的内容?

如何在iOS 17 SwiftUI中获取用户名

安装新版本 XCode 15.0 后无法运行应用程序 XCode

AVAudioRecord 没有音频

如何结合`@dynamicMemberLookup`和`ExpressibleByStringInterpolation`来实现方法链?

带有属性包装器的不可用属性

如何在不同设备的segment控制中管理文本大小(text size)?

Swift 错误:在其自己的初始值中使用的变量

如何使用 Swift 从assets资源 中加载特定图像

导航控制器自定义过渡动画

如何进行键值观察并在 UIView 的框架上获取 KVO 回调?

xcode 5.1:libCordova.a 架构问题