UIMenuController не отвечает на первый выбор, только второй - PullRequest
0 голосов
/ 14 марта 2012

У меня есть вид с длинным нажатием распознавателя жестов:

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {            
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDetected:)];
        [self addGestureRecognizer:longPress];
        [longPress release];
    }
    return self;
}

Когда долгое нажатие обнаружено, я хочу показать UIMenuViewController над представлением с одним действием в нем, и когда этот пункт меню коснулся, я хочу выполнить блок:

- (void)longPressDetected:(UILongPressGestureRecognizer *)recognizer {
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        [self becomeFirstResponder];
        UIMenuController *menuController = [UIMenuController sharedMenuController];
        UIMenuItem *actionItem = [[UIMenuItem alloc] initWithTitle:@"Action" action:@selector(someActionSelector)];
        [menuController setMenuItems:[NSArray arrayWithObject:actionItem]];
        [actionItem release];

        [menuController setTargetRect:self.frame inView:self.superview];
        [menuController setMenuVisible:YES animated:YES];
    }
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (action == @selector(copy:) || action == @selector(cut:) || action == @selector(delete:) || 
        action == @selector(paste:) || action == @selector(select:) || action == @selector(selectAll:)) {
        return NO;
    }
    else if (action == @selector(someActionSelector)) {
        return YES;
    }
    else {
        return [super canPerformAction:action withSender:sender];
    }
}

- (void)someActionSelector {
    if (self.actionBlock) {
        self.actionBlock();
    }
}

Проблема в том, что это работает только после второго длительного нажатия и касания комбо. В первый раз, когда я долго нажимаю на вид, я вижу меню, но касание меню ничего не делает. Во второй раз, когда я снова вижу меню, я нажимаю на него, затем выполняется блок.

Отладчик показывает, что точка останова в someActionSelector достигается только при втором нажатии. Есть идеи, почему это так?

1 Ответ

0 голосов
/ 14 марта 2012

Я понял это. Представление, прослушивающее долгое нажатие, содержится внутри представления, которое перемещает некоторые подпредставления при изменении его кадра (путем переопределения setFrame:, что кажется плохой идеей, но я не мог придумать другой способ). Поэтому, когда произошло долгое нажатие, это вызвало layoutSubviews в родительском элементе родительского вида представления для прослушивания, которое установило рамку родительского элемента в виде для прослушивания, которое переместило прослушивающее представление, которое, по-видимому, разрывает либо цепочку респондента, либо деактивировать меню. Решением было добавить условие внутри переопределенного setFrame:, чтобы активировать макет только в том случае, если кадр действительно изменяется, чего не происходит при длительном нажатии. Я уверен, что есть лучшая альтернатива для прослушивания изменений кадра, которая полностью избежала бы этой проблемы - не стесняйтесь предлагать их в комментариях.

...