2010-04-06 4 views
3

Я использую шаблон с разделенным видом, чтобы создать простой вид с разделом, который, конечно же, представляет собой popover в режиме Portrait. Я использую код по умолчанию, сгенерированный шаблоном, который добавляет/удаляет элемент панели инструментов и устанавливает контроллер popover и удаляет его. Эти два метода - splitViewController: willShowViewController: ... и splitViewController: willHideViewController: ...Как подключиться к методу действий для кнопки панели навигации iPad?

Я пытаюсь выяснить, как заставить popover исчезнуть, если пользователь нажимает кнопку на панели инструментов во время отображения popover. Вы можете заставить popover исчезнуть, не выбирая элемент, если вы нажмете куда-либо вне popover, но я также хотел бы, чтобы он исчез, если пользователь снова нажал кнопку.

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

Могу ли я как-то написать действие и установить его на элемент панели инструментов, не переопределяя действие, которое уже существует? например добавить действие, которое вызывает тот, который есть сейчас? Или мне нужно написать действие, которое отображает/скрывает сам popover (поведение, которое выполняется за кулисами, предположительно, с помощью контроллера разделенного вида сейчас?).

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

Спасибо!

ответ

6

Так получается, что вы можете сделать поповер отклонить при нажатии на barButtonItem путем внедрения метода SplitViewController willPresentViewController следующим образом:

- (void) splitViewController:(UISplitViewController *)svc 
      popoverController: (UIPopoverController *)pc 
    willPresentViewController: (UIViewController *)aViewController 
{ 
    if (pc != nil) { 
     [pc dismissPopoverAnimated:YES]; 
    } 
} 
1

Итак, barButtonItem будет иметь UISplitViewController в качестве цели и showMasterInPopover: как действие. Я не могу найти его в документации, поэтому я немного волнуюсь, что это нехорошо назвать это, но я получил его для работы, изменив цель на себя (контроллер представления) и действие на пользовательский метод, например это:

- (void)showMasterInPopover:(id)sender { 
    // ...insert custom stuff here... 
    [splitViewController showMasterInPopover:sender]; 
} 
-1

Элизабет пишет:

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

Прежде всего, позвольте мне сказать, что ничто из того, что я собираюсь сказать, должно быть принято лично - это не значит, что так. Все это происходит с лет разработки интерфейсов программирования и изучения Руководства по человеческому интерфейсу Apple (а также с графическим дизайнером, который постоянно пытается, чтобы научить меня правильному способу делать что-то). Это подразумевается как противоположная точка зрения, а не как разглашение.

Что вы предлагаете, это проблема UI-мудрый для меня, и это будет проблемой, которая вызывает проблемы, когда Apple проверяет приложение. Вы никогда не должны иметь известный объект UI, выполняющий функцию, которую он не выполняет нормально (например: кнопка никогда не показывает , а затем выпускает представление/объект/окно. Включает это).

Например, увеличительное стекло на навигационной панели означает поиск (как определено Apple). Они в прошлом и будут продолжать в будущем, отказаться от приложений, которые используют это для масштабирования интерфейса. Например: Apple Rejects ConvertBot или The Odyssey: Trail of Tears (поиск по этой странице).Язык в отрицании всегда одинаково (полужирный маркировки, что они цитируют для использования):

«... использует стандартные изображения экрана iPhone/IPod в нестандартным образом, потенциально может привести к путанице. Изменение поведения стандартной iPhone-графики, действий, а также изображения или имитация сбоев в отношении этих графических изображений, действий или изображений является нарушением соглашения о Программе разработчиков iPhone, которое требует от приложений соблюдения Руководства по человеческому интерфейсу. »

Кроме того, если вы действительно хотите эту функцию, спросите себя: «Почему?». Если это потому, что ты сам, как и я, я бы действительно пропустил это. Большинство пользователей были бы смущены этим поведением и на самом деле не использовали бы его, потому что они не знали, что это вариант использования. Apple потратила последние 3 года на обучение пользователей iPhoneOS, как использовать их ОС и интерфейсные элементы. Последнее, что вы, как программист или дизайнер, хотите сделать, это потратить время, пытаясь обучить пользователя тому, как использовать ваше приложение. Они, как правило, удаляют ваше приложение со своего устройства и переходят в другое подобное приложение, вместо того, чтобы заставлять себя учиться вашего способа делать вещи.

Только мой $ .02

+0

Такое поведение является довольно стандартным, я видел его на много приложений (а также документация веб-приложений Apple, сделанная так, чтобы выглядеть как popover - он тоже делает это). – Elisabeth

+0

@Jann Ознакомьтесь с iBooks или Instapaper. Я согласен с Elisabeth & Marco: http://twitter.com/marcoarment/status/11767179703 – gerry3

0

Не имеет репутацию, чтобы сделать реальный комментарий. :-(

@Jann - Я уверен, что Элизабет хочет сделать это довольно стандартно. Например, приложение Notes, которое поставляется с предварительно загруженным на iPad, закрывается и открывает popover, когда вы нажимаете кнопку на панели инструментов в верхний левый угол

0

Ниже приводится мое решение. Оно начинается аналогично решению greenisus, подключая обработчик событий кнопки панели инструментов UISplitViewController.Я использую флаг в контроллере, чтобы отслеживать, открыт ли popover или нет. Наконец, чтобы обработать случай, когда пользователь открывает popover, затем закрывает его, вызывая за пределами popover, я реализую протокол UIPopoverControllerDelegate.

Во-первых, контроллер inte rface:

@interface LaunchScene : NSObject <UISplitViewControllerDelegate, UIPopoverControllerDelegate> 
{ 
    UISplitViewController* _splitViewController; //Shows list UITableView on the left, and details on the right 
    UIToolbar* _toolbar;       //Toolbar for the button that will show the popover, when in portrait orientation 
    SEL _svcAction;         //The action from the toolbar 
    id _svcTarget;         //The target object from the toolbar 
    UIPopoverController* _popover;     //The popover that might need to be dismissed 
    BOOL _popoverShowing;       //Whether the popover is currently showing or not 
} 

-(void) svcToolbarClicked: (id)sender; 

Я использую _svcAction и _svcTarget к addess заботы greenisus о том, что он не может называть правильную функцию.

Ниже приводится моя реализация. Для краткости я пропустил код, который создает экземпляр UISplitViewController и subviews. Отображается весь отображаемый/скрытый код.

//the master view controller will be hidden so hook the popover 
- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)pc 
{ 
    _popoverShowing = FALSE; 
    if(_toolbar == nil) 
    { 
     //set title of master button 
     barButtonItem.title = @"Title goes here"; 

     //Impose my selector in between the SVController, and the SVController's default implementation 
     _svcTarget = barButtonItem.target; 
     _svcAction = barButtonItem.action; 
     barButtonItem.target = self; 
     barButtonItem.action = @selector(svcToolbarClicked:); 

     //create a toolbar 
     _toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 1024, 44)]; 
     [_toolbar setItems:[NSArray arrayWithObject:barButtonItem] animated:YES]; 
    } 

    //add the toolbar to the details view (the second controller in the splitViewControllers array) 
    UIViewController* temp = [_splitViewController.viewControllers objectAtIndex:1]; 
    [temp.view addSubview:_toolbar]; 
} 

Вот моя функция, которая реагирует на щелчок на панели инструментов. Это обрабатывает случай, когда пользователь нажимает кнопку и нажимает кнопку панели инструментов.

-(void) svcToolbarClicked: (id)sender 
{ 
    if(_popoverShowing) 
    { 
     [_popover dismissPopoverAnimated:TRUE]; 
    } 
    else 
    { 
     //Perform the default SVController implementation 
     [_svcTarget performSelector:_svcAction]; 
    } 
    //Toggle the flag 
    _popoverShowing = !_popoverShowing; 
} 

Некоторые функции от UISplitViewControllerDelegate

//the master view (non-popover) will be shown again (meaning it is going to landscape orientation) 
- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)button 
{ 
    //remove the toolbar 
    [_toolbar removeFromSuperview]; 
} 

// the master view controller will be displayed in a popover (i.e. the button has been pressed, and the popover is about to be displayed. 
//Unfortunately triggers when the popover is ALREADY displayed. 
- (void)splitViewController:(UISplitViewController*)svc popoverController:(UIPopoverController*)pc willPresentViewController:(UIViewController *)aViewController 
{ 
    _popover = pc; //Grab the popover object 
    _popover.delegate = self; 
} 

Приведенный выше код является достаточным для большинства случаев. Однако, если пользователь открывает popover, а затем отклоняется, щелкнув в другом месте на экране, логическое значение _popoverShowing будет содержать неправильное значение, которое заставит пользователя дважды нажать кнопку панели инструментов, чтобы повторно открыть popover. Чтобы исправить это, примените метод UIPopoverControllerDelegate, как показано ниже.

//UIPopoverControllerDelegate method 
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController 
{ 
    _popoverShowing = FALSE; 
    _popover = nil; 
} 

Это взял меня навсегда, чтобы выяснить, копаться в документации и (я думаю) большинство вопросов UISplitViewController на StackOverflow. Надеюсь, кто-то сочтет это полезным. Если это так, я жажду репутации. ;-)

+0

Вау, спасибо! Я обязательно попробую это и дам вам знать, если это сработает :-) – Elisabeth

0

Может быть, вы все только усложнит его слишком много или я читать что-то совсем другое, чем вы, ребята хотели сделать ... но, возможно, это то, что вы все пытались выяснить так жестковата:

-(void)togglePopOverController { 

if ([popOverController isPopoverVisible]) { 

[popOverController dismissPopoverAnimated:YES]; 

} else { 

[popOverController presentPopoverFromBarButtonItem:bbiOpenPopOver permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 

} 

} 
+0

Ну, сложная часть выясняет, где подключиться к методам делегата splitViewController. См. Мое решение ниже. – Elisabeth

 Смежные вопросы

  • Нет связанных вопросов^_^