UISplitViewController и сложная иерархия представлений - PullRequest
9 голосов
/ 14 апреля 2010

Я делаю демонстрацию технологии iPad и столкнулся с серьезной технической проблемой.

У меня есть концепция приложения, которая использует UISplitViewController, но НЕ как основной контроллер для всего приложения.

Поток приложения можно описать примерно так:

Главный экран (UIViewController) Список-> Деталь "Каталог" (UISplitViewController) Экран сверхвысокой детализации (UIViewController, но он также может быть дочерним для SplitView).

Проблема в потоке между Домом и Каталогом. Как только представление UISplitViewController добавляется в окно UIWindow, оно начинает выбрасывать его шипучие припадки.

Проблема может быть обобщена следующим образом:

Когда UISplitView генерирует всплывающее представление, оно, кажется, затем привязывается к своему родительскому представлению. После удаления UISplitView из подпредставлений UIWindow вы получите исключение CoreGraphics, и представление не удастся удалить.

При добавлении других представлений (предположительно, в данном случае на домашний экран, на который вы возвращаетесь) они не автоматически поворачиваются, вместо этого UISplitView, который не удалось удалить из-за исключения CG, продолжает отвечать на запросы. вместо этого вращение, вызывающее ужасные ошибки рендеринга, с которыми нельзя просто "справиться". На этом этапе добавление любых представлений, даже повторное добавление SplitView, вызывает каскад ошибок рендеринга.

Затем я попытался просто оставить SplitView всегда представленным как «нижний» вид и продолжать добавлять и удалять домашний экран сверху, но это не удается, поскольку SplitView доминирует над вызовами изменения ориентации, а домашний экран не будет повернуть, даже если вы вызываете [homeScreen intoFirstResponder]

Вы не можете поместить SplitView в иерархию, такую ​​как UINavigationController, вы получите прямую ошибку времени выполнения, так что эта опция не будет рассмотрена. Модалы просто выглядят плохо и в любом случае обескураживают.

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

Если вы хотите увидеть приложение, которое делает именно то, что мне нужно, проверьте GILT Groupe в магазине приложений iPad. Они сделали это, но, похоже, запрограммировали весь набор пользовательских переходов.

Помощь будет принята с благодарностью.

Ответы [ 6 ]

8 голосов
/ 15 апреля 2010

Apple состояния :

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

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

Вы никогда не должны представлять разделенное представление внутри интерфейса навигации или панели вкладок

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

У меня такое ощущение, что то, что вы испытываете, является побочным продуктом попытки сделать это. Я действительно удивлен, что приложение GILT Groupe не было отклонено. Apple в последнее время довольно строго соблюдает эти правила HIG. Они (как вы уже узнали) вызывают довольно неприятную ошибку во время выполнения, когда вы пытаетесь добавить их в NavigationController.

4 голосов
/ 03 мая 2010

Я добился определенного успеха, создав второе окно UIWindow. Я связываю UISplitViewController с этим и переключаю его в главное окно, когда хочу показать splitview. Кажется, они работают так, как я хотел, за исключением небольшой задержки поворотов и сообщения журнала о "wait_fences".

4 голосов
/ 16 апреля 2010

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

Это неприятный способ сделать что-то в моей книге, но Apple оставляет вам небольшой выбор, если вы хотите использовать SplitView только «иногда» в приложении.

0 голосов
/ 06 мая 2011

Просто хотел сказать, что я сталкивался с этими же проблемами, нашел эту тему на форуме и следовал совету из g051051 выше. Это прекрасно работает для меня. Я не вижу никаких сбоев и сообщений о wait_fences в консоли устройства.

Я просто использовал IB, чтобы создать два объекта UIWindow в основной XIB, как обычно созданный UISplitViewController, а затем также экземпляр моего другого контроллера, производного от UIViewController (который я использую для полноэкранного отображения). Я просто подключил их, подключив rootViewController для каждого UIWindow к соответствующему контроллеру.

В приложении: didLaunch ...: метод Я могу решить, какое окно отправить методу makeKeyAndVisible, а какое - скрытому. Когда пользователь хочет переключаться назад и вперед, я просто должен отправить makeKeyAndVisible одному и установить скрытое свойство для другого, и это все, что нужно сделать.

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

Во всяком случае, прекрасно работает для меня, и на самом деле довольно легко настроить.

0 голосов
/ 17 сентября 2010

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

Кажется, я нашел решение для моего дела, которое, кажется, работает удовлетворительно.

Ключом является то, что первый вид, добавленный в UIWindow, является единственным видом, правильно инициализированным. Все проблемы, которые у меня были, как правило, связаны с неправильным уведомлением об ориентации устройства. Первое добавленное представление, по-видимому, правильно настроено.

В моем случае я не хотел UISplitView в качестве первого представления. Следующее работает для меня.

Приложение-делегат приложения: метод didFinishLaunching является специальным. Добавление вида в UIWindow должно произойти здесь. Если это сделано в другом месте, оно не будет настроено должным образом.

По сути, это волшебный соус, первый вид которого будет добавлен в окно. Затем можно удалить его, пока вы сохраняете UISplitViewController. С этого момента вы можете поменять местами другие представления, включая UISplitView, и большинство вещей, кажется, в порядке.

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

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

Вот код, если он помогает. Все контроллеры являются переменными экземпляра appDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // This also seems to work as good magic. Seems to set orientation and size properties that persist.
    [window addSubview:splitViewController.view];
    [splitViewController.view removeFromSuperview];

    [self switchToNewViewController:firstController];
    [window makeKeyAndVisible];
    return TRUE;
}

- (void)switchToNewViewController:(UIViewController *)newViewController {
    [popoverController dismissPopoverAnimated:FALSE];
    if (newViewController != currentViewController) {
        [currentViewController removeFromSuperview];
        currentViewController = newViewController;
        [window addSubView:newViewController.view];
     }
}
0 голосов
/ 04 июля 2010

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

Кроме того, приложение Gilt доступно только в США

Я тоже пытался найти решение и закончил тем, что программно удалял виды из окна, как говорит Туаннд, но ошибка рендеринга ландшафта непростительна.

@ Jasconius, какое максимальное количество модалов вы представляете в любое время?

...