摘要:我想要做的就是擁有一個 UIControl 子類,它在按下時顯示 UIMenu,我已經閱讀了另一個問題,但是在將 contextMenuinteractionEnabled 屬性設定為 YES 時我遇到了崩潰。
類似問題:來自 UIView 的 iOS 14 背景關系選單(不是來自 UIButton 或 UIBarButtonItem)
我有一個 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"
但是當運行它時,我收到以下錯誤訊息:
錯誤資訊
*** 斷言失敗 -[MyControl addInteraction:], UIView.m:17965
*** 由于未捕獲的例外“NSInternalInconsistencyException”而終止應用程式,原因:“無效引數不滿足:互動”
錯誤:NSInternalInconsistencyException
原因:無效引數不滿足:互動
堆疊跟蹤: (
0 核心基礎 0x00000001b8181e94 5CDC5D9A-E506-3740-B64E-BB30867B4F1B 40596
1 libobjc.A.dylib 0x00000001b14b78d8 objc_exception_throw 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”而終止應用程式,原因:“無效引數不滿足:互動”以 NSException 型別的未捕獲例外終止
問題
錯誤訊息“無效引數不滿足:互動”是什么意思?“互動”從何而來,如何解決?
我究竟做錯了什么?我想要的只是一個可以在按下時顯示選單的自定義 UIControl。而已。
作為旁注,這段代碼適用于 UIButton 實體,因此 UIButton 類正在做一些我沒有做的內部事情,但我不知道是什么。
更新 1
根據@DonMag 的回答,我嘗試了這個:
MyControl *control = [[MyControl alloc] init];
control.showsMenuAsPrimaryAction = YES;
UIContextMenuInteraction *contextMenuInteraction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
[control addInteraction:contextMenuInteraction];
[self.view addSubview:control];
這不再崩潰,如果我長按它甚至會顯示選單。但我希望它能像常規選單一樣顯示,作為按下控制元件的主要操作。我想做的是模擬menuUIButton 上的屬性。如果我可以實作一個具有選單屬性的控制元件,然后讓該選單作為主要操作可用,那將是最理想的事情。
uj5u.com熱心網友回復:
沒必要打電話.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
編輯
稍作修改以允許單擊(主要操作):
#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
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/537853.html
