UISplitViewController: Как заставить показывать мастер-поповер при запуске приложения? (портрет)

В приложении для iPad я использую UISplitViewController. Мне нужно заставить показывать мастер поповер при запуске приложения в портретном режиме.

Сейчас я использую этот код, и он хорошо работает на iOS 5.0.

<code>if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
   if ([[[AppDelegate sharedAppDelegate] splitViewController] respondsToSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]) {
      [[[AppDelegate sharedAppDelegate] splitViewController] performSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]];
   }            
}
</code>

Но в iOS 5.1 (с новым типом master popover) поведение кажется случайным. Иногда поповер показывает в полноэкранном режиме, а иногда работает хорошо.

Некоторые предложения для 5.1?

 akofink26 апр. 2013 г., 17:59
Вот хороший ответ:stackoverflow.com/a/15817100/733862

Ответы на вопрос(8)

let btn = self.splitViewController!.displayModeButtonItem()
btn.target?.performSelector(btn.action, withObject: btn)

переопределите этот метод в контроллере подробного представления:

-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
    return NO;
}

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

 10 дек. 2014 г., 11:56
Это не рекомендуется в iOS 8.
 16 окт. 2014 г., 21:56
Спасибо! Это должен быть принятый ответ.

ите ту же цель / действие. Смотри мой ответhttps://stackoverflow.com/a/25695923/1021430

Целью является контроллер разделенного представления, а действие - toggleMasterVisible:

 08 сент. 2014 г., 22:39
Этот toggleMasterVisible является закрытым методом.

Теперь с iOS8, есть куча новых методов дляUISplitViewController конфигурации.

В вашем случае просто установите правильное значение вpreferredDisplayModeнапример в masterViewControllerviewDidLoad.

Objective-C:

- (void)viewDidLoad {
    // configuring splitviewcontroller
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;

    //....
}

Swift:

    override func viewDidLoad() {
        self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
    }

Но это, конечно, только iOS8.

 23 дек. 2017 г., 14:19
также может быть вызван в detailViewController
 10 дек. 2014 г., 11:55
Это заставляет параллельное отображение. Он не показывает главное представление в режиме всплывающего окна в соответствии с запросом OP.
 25 июн. 2015 г., 19:18
@phatmann, я не думаю, что alejandromp говорил о поповере. Он говоритI need to force to show the master popover но на самом деле это ничего не значит. Рассматривая контекст, он говорит об отображении главного вида рядом в портретном режиме, как в альбомной ориентации.
Решение Вопроса

и даже сейчас я не на 100% доволен решением, но это единственное, что мне удалось придумать, учитывая текущие ограничения.

Сначала переопределите следующий метод делегата:

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController

и использовать его, чтобы получить ссылку на элемент панели кнопок и сохранить его в iVar:

barButtonForMaster = barButtonItem;

Затем, когда вы хотите показать основной контроллер вида, сделайте вызов, подобный этому:

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster];

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

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster afterDelay:1];

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

 17 дек. 2013 г., 16:13
Это приведет к возможному предупреждению утечки памяти компилятором
 alejandromp05 мая 2012 г., 13:51
Благодарю. Я делаю это с вашим кодом плюс мой предыдущий код. Но иногда приложение вылетает. Я думаю, что это потому, что я делаю это в делегате splitViewController и, возможно, в некоторых случаях, в контроллере, который он создал не полностью. Теперь я делаю этот код с perfromSelectorAfterDelay и работаю очень хорошо. Благодарю.

это хорошо работает для меня (в viewDidLoad подробного экрана):

//If in portrait mode, display the master view
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    [self.navigationItem.leftBarButtonItem.target performSelector:self.navigationItem.leftBarButtonItem.action withObject:self.navigationItem];
}

Нет необходимости извлекать отдельную ссылку, используя вместо этого self.navigationItem.leftBarButtonItem

 13 мар. 2013 г., 13:58
удивительно спасибо.
 12 мар. 2013 г., 16:57
это удивительно и работает отлично! это предупреждает меня: «PerformSelector может вызвать утечку, потому что его селектор неизвестен». Вы знаете, почему и что с этим делать?
 08 сент. 2014 г., 22:58
Это не работает, если в контроллере подробного представления ничего не загружено, что было бы главной причиной, заставляющей мастер показывать.
 28 нояб. 2014 г., 08:39
@VictorEngel это делает, но так как этот код входит в подробный вид, вам необходимо убедиться, что по умолчанию загружен пустой подробный вид.
 13 мар. 2013 г., 08:50
AFAIK компилятор анализирует вызовы методов и добавляет код для управления счетчиками ссылок ARC (для управления сборкой мусора). Вызов такого метода подобен использованию отражений в Java (выполняется во время выполнения), поэтому в этом случае компилятор не может использовать магию refCount. Однако до тех пор, пока вызываемый метод не возвращает какой-либо выделенный объект (который затем будет утечкой), это не будет проблемой. В этом случае мы ничего не возвращаем из вызванного метода. Чтобы избежать этого предупреждения, смотрите:learningipadprogramming.com/2012/04/03/…

 self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;

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

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic


В splitViewController в viewDidLoad установите displayMode в .primaryOverlay

override func viewDidLoad() {
    if self.isCollapsed == false, self.displayMode == .primaryHidden {
        self.preferredDisplayMode = .primaryOverlay
    }
}

И в viewWillAppear установите его обратно .automatic

override func viewWillAppear(_ animated: Bool) {
    self.preferredDisplayMode = .automatic
}

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

Ваш ответ на вопрос