iOS - PopOver презентация и увольнение - PullRequest
1 голос
/ 24 февраля 2012

У меня есть UIToolbar вверху главного экрана моего приложения для iPad.На нем есть 6 элементов UIBarButton.4 из этих элементов вызывают появление UIPopOvers.Другие 2 элемента либо переключаются на другое представление, либо изменяют что-то в текущем представлении.

3 из 4 UIPopOvers появляются из повернутого UIBarButtonItem, четвертое появляется без стрелки в середине экрана.

Мне бы хотелось получить следующую функциональность, но у меня возникли трудности при ее получении:

  1. Когда UIPopOvers не отображаются, и пользователь касается одного из UIBarButtonItems, который генерирует UIPopOver, показать, что UIPopOverдовольно просто, все заработало.)
  2. Когда отображается UIPopOver и пользователь касается UIToolbar, отклонить этот UIPopOver.(Получил эту работу, используя UIGestureRecognizer, который занимает 1 нажатие.)
  3. Когда отображается UIPopOver и пользователь нажимает UIBarButtonItem, КОТОРЫЙ UIPopOver «TIED», отклоняет UIPopOver.(Вот проблема для меня.)
  4. Когда отображается UIPopOver, и пользователь касается другого UIBarButtonItem, отклоняет текущий UIPopOver и показывает соответствующий новый.(Это работает нормально.)

Итак, проблема, с которой я сталкиваюсь, заключается в том, что UIGestureRecognizer срабатывает до нажатия кнопки.Я также не могу найти хороший способ «отказаться» от UIGestureRecognizer, когда пользователь нажимает UIBarButtonItem (таким образом, только запускает действие UIGestureRecognizer, когда сам UIToolbar нажат, а не UIBarButtonItem).Конечным результатом этого является то, что когда отображается UIPopOver (из UIBarButtonItem), и пользователь касается того же UIBarButtonItem, UIPopOver отклоняется, а затем снова появляется.

Я пытаюсь избежать некоторыхпроблема с синхронизацией, когда я установил флаг «toolbarTapped» в значение «YES» на 0,10 секунды, а затем снова установил для него значение «NO» (или что-то в этом роде).(а не хак-у).

Кажется, я не могу найти способ определить, когда UIGestureRecognizer был запущен на основе касания UIBarButtonItem, так как UIGestureRecognizer запускается первым, и, похоже, это не очень хорошо.(не частный) способ получить фрейм UIBarButtonItem.

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

Вот код для UIGestureRecognizer:

// Initialization
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(removeAllPopOvers)];
[tapRecognizer setCancelsTouchesInView:NO];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setNumberOfTouchesRequired:1];
[[self Toolbar] addGestureRecognizer:tapRecognizer];

// Tap handler
- (void)removeAllPopOvers {
    NSLog(@"removing all popovers");
    if ([self firstPopOver]) {
        [[self firstPopOver] dismissPopoverAnimated:YES];
        [self setFirstPopOver:nil];
    }
    // and so on with the rest...
}

А вот как отображается один из моих UIPopOvers:

- (IBAction)showSettings:(id)sender {
    NSLog(@"settings button tapped");
    if (![self SettingsPopOver]) {
        SettingsViewController *settingsVC = [[SettingsViewController alloc] initWithNibName:@"SettingsView-iPad" bundle:nil];
        UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:settingsVC];
        [popOver setDelegate:self];
        [self setSettingsPopOver:popOver];
        [[self SettingsPopOver] setPopoverContentSize:CGSizeMake(320, 300)];
        [[self SettingsPopOver] presentPopoverFromBarButtonItem:[self Settings] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
}

Чистый эффект всего этого заключается в том, что я могу выбрать один из следующих двух вариантов (но не оба):

  1. Разрешить UIBarButtonItem отклонить UIPopOver.
  2. Разрешить касанием UIToolbar отклонить UIPopOver.

Есть идеи?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 24 февраля 2012

для выпуска 3:

if ([self.popoverController isPopoverVisible])
    [self.popoverController dismissPopoverAnimated:YES];
else

, если всплывающее окно видно, оно отклонит его;иначе вы создаете поповер.

для остальных, хотите ли вы, чтобы всплывающее окно отклонялось только при касании панели инструментов?если пользователь коснется где-нибудь еще на экране, вы хотите, чтобы поповер остался?

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

https://developer.apple.com/library/ios/#documentation/uikit/reference/UIPopoverController_class/Reference/Reference.html

0 голосов
/ 21 марта 2015

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

(BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer      
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer
{
  return YES;
}
0 голосов
/ 24 февраля 2012

На данный момент я реализовал что-то, что работает, но не элегантно (по крайней мере, я так не думаю).

По сути, я задерживаю действие из UIGestureRecognizer, отправляя его сначала в метод «буфера»:

#pragma mark - PopOver Dismissal
// dismissAllPopOversBuffer is called as the action of my UIGestureRecognizer
- (void)dismissAllPopOversBuffer {
    NSLog(@"dismiss all popovers buffer...");
    [self performSelector:@selector(dismissAllPopOvers) withObject:nil afterDelay:0.1];
}
- (void)dismissAllPopOvers {
    NSLog(@"dismissing all popovers");
    // actual dismissal logic
}

Как видите, это выталкивает фактическую логику увольнения на 0,1 секунды. Затем в каждом из методов нажатия кнопки я делаю это:

#pragma mark - UIBarButtonItem Press Event Handlers
- (IBAction)buttonPressed:(id)sender {
    [NSObject cancelPreviousPerformRequestsWithTarget:self
                                             selector:@selector(dismissAllPopOvers)
                                               object:nil];
    // The rest of the logic to dismiss/show UIPopOver
}

Пока что мое тестирование показывает, что оно работает. Исходя из временных отметок NSLog, фактическое время, прошедшее между действием UIGestureRecognizer и событием UIBarButtonItem, обычно составляло 1 миллисекунду (0,001 секунды), поэтому вытеснение 0,1 секунды (или 100-кратного нормального промежутка времени) ДОЛЖНО быть безопасным большую часть времени, но я по-прежнему не нравится.

Я бы хотел найти способ определить, когда пользователь нажал на UIToolbar, но не на какой-либо из UIBarButtonItems. Это кажется довольно простым (логически), но довольно трудным (практически).

...