1

I have assigned two UILongPressGestureRecognizer objects to a UIButton.

First one, is named longPressGestureRecognizer and has minimumPressDuration = 0.5

Second one, is named prolongedPressGestureRecognizer and has minimumPressDuration = 1.5

self.longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];

        self.longPressGestureRecognizer.delegate = self;
        
        self.longPressGestureRecognizer.minimumPressDuration = 0.5;
        
        self.longPressGestureRecognizer.numberOfTouchesRequired = 1;
        
        self.longPressGestureRecognizer.numberOfTapsRequired = 0;
        
        self.longPressGestureRecognizer.allowableMovement = 10.0;
        
        [self.customButton addGestureRecognizer:self.longPressGestureRecognizer];
     
        self.prolongedPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(prolongedPress:)];
        
        self.prolongedPressGestureRecognizer.delegate = self;
        
        self.prolongedPressGestureRecognizer.minimumPressDuration = 1.5;
        
        self.prolongedPressGestureRecognizer.numberOfTouchesRequired = 1;
        
        self.prolongedPressGestureRecognizer.numberOfTapsRequired = 0;
        
        self.prolongedPressGestureRecognizer.allowableMovement = 10.0;
        
        [self.customButton addGestureRecognizer:self.prolongedPressGestureRecognizer];

Scenarios:

When the first one fires I'd like for something to happen.

When the second one fires I'd like for the context menu to show.

Currently, I have no way to do this.

Solutions:

  1. Is it possible to delay the time it takes for the context menu to appear? I'm sure there's a long press gesture recognizer internally that shows the menu. Can I modify this gesture recognizer?

2. Is it possible to show the menu programmatically?

        NSMutableArray* actions = [[NSMutableArray alloc] init];

        [actions addObject:[UIAction actionWithTitle:@"Edit"
                                               image:nil
                                          identifier:nil
                                             handler:^(__kindof UIAction* _Nonnull action) {
            
            // ...
        }]];

        UIMenu* menu =
        [UIMenu menuWithTitle:@""
                     children:actions];
        
        self.customButton.menu = menu;
Vulkan
  • 1,004
  • 16
  • 44

1 Answers1

0

You probably need something like this. self.layoutButton shows the menu as a primary action. It means normal tap. Not a primary action is a long tap.

NSMutableArray<UIAction *> *actions = [NSMutableArray array];
__weak __typeof__(self) blockSelf = self;
for (NSString *type in sortedKeys) {
        ZoneLayout *layout = [LayoutManager layoutByType:type];
        UIAction *action = [UIAction actionWithTitle:layout.title image:nil identifier:type
                                             handler:^(__kindof UIAction * _Nonnull action) {
                __strong __typeof__(blockSelf) strongSelf = blockSelf;
                if (strongSelf) {
                        strongSelf.layoutType = type;
                        [strongSelf setupZoneLayoutMenu];
                }
        }];
        if ([self.layoutType isEqualToString:type])
                action.state = UIMenuElementStateOn;
        else
                action.state = UIMenuElementStateOff;
        [actions addObject:action];
}
ZoneLayout *layout = [LayoutManager layoutByType:self.layoutType];
if (layout != nil)
        [self.layoutButton setTitle:layout.title forState:UIControlStateNormal];
else
        [self.layoutButton setTitle:@"-" forState:UIControlStateNormal];
self.layoutButton.menu = [UIMenu menuWithChildren:actions];
self.layoutButton.showsMenuAsPrimaryAction = YES;
Cynichniy Bandera
  • 5,991
  • 2
  • 29
  • 33
  • I need to show the menu after a very long tap. Not long press. Not tap. But a very long press. After 1.5 sec. – Vulkan Sep 23 '22 at 21:59
  • AFAIK there is no such way and it seems it is done on purpose ) To do so you would need to re-implement UIMenu yourself. – Cynichniy Bandera Sep 25 '22 at 16:38