Адаптивный сегмент в раскадровке Xcode 6. Толчок устаревшие?


Xcode 6 interface builder по умолчанию имеет новый флажок "Использовать классы размеров". Это делает взгляды адаптивными.

когда я пытаюсь сделать переход между 2 видами в моей раскадровке у меня есть новые варианты:

вместо старого:

теперь у нас есть "шоу" и "представить модально" вместо "push" и "модальные". Старые параметры помечены как устаревшие. Я выбрал опцию "Показать", потому что в настройках segue она называется " показать (например push)

но это не делает толчок. Анимация Segue выглядит как слайд снизу (модальный), а панель навигации исчезает.

вопрос: Как я могу заставить "шоу" работать как толчок? Это возможно или я должен использовать" push (deprecated) " вместо этого? Где я могу найти информацию о новых видах переход? Единственное, что я нашел в библиотеке разработчиков iOS8-это Раскадровки Помогут Вам Создать Свой Пользовательский Интерфейс но нет никакой информации про "показать" переход.

обновление

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

if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
    SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;

    swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {

        UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
        [navController setViewControllers: @[dvc] animated: NO ];
        [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
    };

}

после этого я стараюсь, чтобы подтолкнуть NewViewController после MainViewController

обновление 2:

Я, кажется, только iOS 7, iOS 7.1 проблема.

7 118

7 ответов:

да, используйте 'Show' вместо 'Push'

Как я могу заставить " шоу " работать как толчок? Это возможно или я должен использовать "push (depricated)" вместо этого?

Это должно; это делает для меня. Я использую Xcode 6 beta 2 и для тестирования я использовал шаблон single view (вызов предварительно сделанного контроллера вида В IB 'VC_A'). Затем я добавил еще один контроллер вида (’VC_B'). Затем я добавил кнопку на VC_A, чтобы показать VC_B и еще один из VC_B обратно в VC_A. когда я добавьте навигационный контроллер в качестве начального контроллера вида в раскадровке и сделайте VC_A rootViewController, оба "push" и "show" имеют одинаковый эффект. Если у меня нет начального навигационного контроллера, и я использую "show", я получаю то, что вы описали в том, что VC_B делает слайд снизу вверх. Если я попытаюсь "нажать", я получу сбой, так как для этого у меня должен быть навигационный контроллер. Похоже, что " шоу " будет делать в случае, когда навигационный контроллер и сделать присутствует с модальным стилем перехода, если навигационный контроллер отсутствует.

где я могу найти информацию о новых типах segue?

поэтому я нашел некоторую информацию в сеансе "что нового в Interface Builder"здесь. Если вы посмотрите на слайды, вы увидите, что один слайд (41) упоминает об изменении. При просмотре этого видео сеанса вы можете перейти к минуте 38: 00, где они начинают говорить об адаптивных сегментах. Они объясняют например, адаптивный сегмент "show" учитывает контекст при принятии решения о том, как сделать презентацию нового контроллера представления.

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

Как уже было сказано, "толчок" и "модальный" объявляет устарели и были заменены на "шоу" и "представить модально" соответственно. Согласно документации Apple, новые сегменты были дополнительно разделены на сегменты, которые адаптируются к классам размеров. Старшие должны использоваться только для поддержки старых версий iOS, чем iOS 8.

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

добавление перехода между сценами в раскадровке

в случае изменения URL в будущем, это объяснение дается для каждого нового сегмента:

показать

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

Показать Детали

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

Присутствует Модально

представить содержание модально. Есть опции для выбора стиля презентации (UIModalPresentationStyle) и стиля перехода (UIModalTransitionStyle).

представить как пирог

представьте содержимое в виде всплывающего окна, привязанного к существующему представлению. Существует возможность указать возможные направления стрелки, показанной на одном краю вида popover (UIPopoverArrowDirection). Существует также возможность указать представление привязки.

tldr; удалить сегмент, который не нажимает правильно и воссоздать его в раскадровке путем перетаскивания из UIView / UIControl к цели контроллер вида.

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

фон

в моем случае ни один из моих сегментов шоу не был работает, даже если у меня уже был UINavigationController в качестве моего начального контроллера вида (с моим содержимым UIViewController, поскольку это root).

Почему и как шоу Segue ломается

Show segue прерывается, когда у него есть действие, связанное с segue в исходном xml раскадровки. Типичный сценарий, вызывающий это, может быть, если вы переопределили сегмент из ручного сегмента, ранее вызванного в коде. Это оставляет следующие биты в раскадровке XML.

<connections>
    <segue destination="85t-Z1-hxf" kind="show" identifier="ToOptions" action="showDetailViewController:sender:" id="gdZ-IX-KcN">
</connections>

Nota Bene для просмотра раскадровки в формате xml; щелкните правой кнопкой мыши файл раскадровки и выберите Открыть как > исходный код. Чтобы отменить использование открыть как > интерфейс Строитель - раскадровка

для размещения любых пользовательских действий при использовании segue из раскадровки можно просто нажать на prepareForSegue и перехватить контроллер вида назначения и вызвать любые методы из этого места. В любом случае, побочный эффект для эта маленькая ошибка (ошибка заключается в том, что при переопределении segue он не правильно настроен в xml ~ т. е. действие остается даже после изменения segue на тот, который работает от UIView (или UIControl) до контроллера целевого вида).

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

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

пример Xml для правильного показа Segue

  <connections>
    <segue destination="RbV-Au-WV9" kind="show" identifier="ToOptions" id="5dm-os-bcS"/>
  </connections>

смягчение последствий

чтобы предотвратить повторение, нужно просто придерживаться не ручных раскадровок, если это возможно, используя prepareForSegue для добавления необходимых действий на основе контроллера вида назначения. Или если вы должны смешивать и сопоставлять, принимать меры предосторожности, чтобы убедиться, что ваши сегменты шоу не имеют никаких действий, вложенных в XML раскадровки. Если вы имеете дело со старыми проектами, то вы должны уделить особое внимание исходному коду раскадровки, поскольку я обнаружил несколько проблем.

Как Скотт Робертсон прокомментировал здесь, это похоже на ошибку в iOS 7.

похоже, что в iOS 8 переход выводится во время выполнения (правильное поведение), в то время как в iOS 7 переход выводится во время разработки (поведение багги).

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

Примечание: моделирование панели навигации недостаточно для этих целей; вы должны фактически иметь навигационный контроллер в своем стеке push.

чтобы воспроизвести ошибку:

  1. создайте новую раскадровку, которая использует классы размеров.
  2. создать два контроллера вида (без навигации контроллеры.)
  3. сделать первый контроллер вида показать второй контроллер вида через показать (например, толчок) segue связан с кнопкой, например.
  4. в коде покажите первый контроллер вида, но вставьте его в навигационный контроллер через initWithRootViewController: метод.
  5. запустите приложение на iOS 7.
  6. Нажмите кнопку, которая должна выполнить толчок.
  7. вы получите модальный переход вместо нажатия на iOS 7. На iOS 8 вы будете получите правильное, толкающее поведение.

enter image description here

исправить ошибку:

  1. добавьте навигационный контроллер в раскадровку и установите первый контроллер вида в качестве корневого контроллера вида. (Примечание: добавление второго в качестве контроллера корневого представления не исправит эту ошибку.)
  2. дайте ему идентификатор нежелательной почты, чтобы подавить предупреждение о недоступности навигационного контроллера и документировать себе, что он существует исключительно как обходной путь. (например,workaround for show segues in iOS 7).

enter image description here

обратите внимание, как навигационный контроллер был добавлен во второй рисунок, и как он не имеет никаких входящих стрелок (т. е. нет никакого способа создать его, кроме использования идентификатора контроллера вида).

Я знаю, что опаздываю на это, но я хотел поделиться тем, что узнал. Это на самом деле ошибка, и все еще присутствует сегодня (2014-12-18).

Я написал об этом статью здесь.

это легко воспроизводимо; на iOS8 будет работать просто отлично и даже в iOS7.x до тех пор, пока вы не нажмете контроллер вида программно в стек перед вызовом Show segue.

если вы только нажимаете на стек с помощью раскадровки соединений он будет работать; но, видимо, если вы нажимаете через код как-то navigationController свойство pushed UIViewController будет nil и Show Он будет считать его модальным, потому что нет навигации для контроля стека.

только обходной путь до сих пор либо не push через код (не представляется возможным), либо использовать теперь устаревший Push.

Я подал радар (ссылка на статью). Не стесняйтесь подавать дубликаты с надеждами Apple, исправляя эту проблему.

у меня была такая же проблема с сегментами в Xcode 7 и iOS 7.1.2. Show segues (новая функция от iOS 8) работает как модальные сегменты в iOS 7 и не позволяйте вам вставлять контроллеры вида в стек навигационных контроллеров, когда вы определяете тип segue с помощью Xcode в своей раскадровке. Вот почему вашей собственной личности.navigationController вернет nil, потому что контроллер вида не был помещен в стек, и вы не можете его вытащить.

Я не понимаю, почему Apple не добавили любые уведомления для этого случая в Xcode, когда вам нужно, чтобы ваше приложение работало на iOS 7. они говорят, что метод Push устарел, но Show не работает правильно с iOS 7.

что я сделал, чтобы решить эту проблему:

Я создал класс MYShowSegue .h

#import <UIKit/UIKit.h>

@interface MYShowSegue : UIStoryboardSegue

@end

и .файл м только с одной выполнить способ:

#import "MYShowSegue.h"

@implementation MYShowSegue

- (void) perform {

    if ([[[self sourceViewController] navigationController] respondsToSelector:@selector(showViewController:sender:)]) {

        id sender = nil;
        [[[self sourceViewController] navigationController] showViewController:[self destinationViewController] sender:sender];
    }else{

        [[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:YES];
    }
}

@end

чем вам нужно установить Custom введите для каждого сегмента в раскадровке и выберите новый класс для него, в моем случае это был MYShowSegue.

Пользовательский Пример Segue

это решение поможет вам получить полную поддержку ваших iOS 7 приложений, они будут использовать pushViewController способ продавить свои взгляды и для iOS 8,9 и т. д. ваш segue будет работать с новым (iOS 8) методом showViewController

Не забудьте сделать то же самое со всеми своими сегментами в раскадровке.

Это все еще происходит в iOS 10.x

удаление и повторная установка сегментов ничего не решили для меня:

проблема: Requred функциональность была 7 сегментов, которые работают только как "толчок" (на самом деле показать деталь), но на самом деле только первый сегмент я добавил бы толкать, остальные будут вести себя модально. Это несмотря на то, что Interface Builder описывает каждый из сегментов одинаково.

решение: мне пришлось добавить действие к 6 сегментам, которые не имели оно.

оригинальная раскадровка XML

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" id="3NK-93-wTy"/>
</connections>

Я изменил это, добавив showViewController: sender

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" action="showViewController:sender:" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" action="showViewController:sender:" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" action="showViewController:sender:" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" action="showViewController:sender:" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" action="showViewController:sender:" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" action="showViewController:sender:" id="3NK-93-wTy"/>
</connections>