UIControl 的 UIContextMenuInteraction

UIContextMenuInteraction for UIControl

我知道 UIButton 有一个 menu 属性 以便可以将上下文菜单添加到按钮。但是对于其他的UIControl子class,比如自定义UIControl,这个属性是不存在的

我知道将上下文菜单添加到 UIControl 的一种方法是调用 addInteraction 然后为上下文菜单采用委托。但是如果我在页面上有多个控件,我该如何为所有不同的控件添加菜单,因为它们都共享同一个委托?

或者,我如何将 menu 属性 添加到我的 UIControl subclass?我知道 UIControl 有一个名为 contextMenuInteraction 的 属性,它显然是自动填充的,但我不明白如何使用那个 属性。我知道控件必须实现委托方法 (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location,但是在该方法中,我是否只构造 UIContextMenuInteraction 对象?当设置了 menu 属性 时,如何让它调用委托方法?

基本上我希望能够在我的 UIControl subclass 中模仿 UIButton class 的 menu 属性。但如果不是那样,那么我至少想弄清楚如何支持共享同一个委托的多个上下文菜单。

您可以创建新的 UIContextMenuInteraction 对象并将其添加到视图(或控件等),方法与添加新手势识别器的方式相同。

然后,在您的菜单操作处理程序中,您可以通过 .sender:

获取被长按以显示菜单的视图
    UIAction *someAction = [UIAction actionWithTitle:@"Some Menu Option"
                                               image:nil
                                          identifier:nil
                                             handler:^(__kindof UIAction* _Nonnull action) {

        // get the view that presented the context menu
        UIView *v = ((UIContextMenuInteraction *)(action.sender)).view;

        // do something
    }];

所以,如果我有一个名为 MySwitch 的自定义 UIControl,并且我想将其中的 7 个添加到堆栈视图中,为每个都提供一个上下文菜单,我可以这样做:

for (int i = 1; i < 8; i++) {
    MySwitch *v = [MySwitch new];
    [v setTitle:[NSString stringWithFormat:@"Switch: %d", i]];
    [v.heightAnchor constraintEqualToConstant:60.0].active = YES;
    UIContextMenuInteraction *interaction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
    [v addInteraction:interaction];
    [stack addArrangedSubview:v];
}