Адаптивний шей в розгортці Xcode 6. Чи застарілий натиск?


121

За замовчуванням у конструктора інтерфейсів Xcode 6 з'явився новий прапорець "Класи розміру". Це робить погляди адаптивними. введіть тут опис зображення

Коли я намагаюся зробити розрив між двома переглядами в моїй раскадровці, у мене з’являються нові варіанти: введіть тут опис зображення

замість старого:

введіть тут опис зображення

Тепер у нас є "показати" та "презентувати модально" замість "push" та "modal". Старі параметри позначаються як застарілі. Я вибрав варіант "показати", тому що в налаштуваннях Segue він називається "показати (наприклад, push)

введіть тут опис зображення

Але це не поштовх. Segue анімація виглядає як слайд знизу (модальний), а навігаційна панель зникає.

Питання: Як я можу зробити так, щоб "шоу" працювало як "push"? Чи можливо це чи потрібно використовувати "push (застаріле)" замість цього? Де я можу знайти будь-яку інформацію про нові типи segue? Єдине, що я виявив у бібліотеці розробників iOS8 - це розклади, які допоможуть вам розробити свій інтерфейс користувача, але немає відомостей про "шоу" segue.

ОНОВЛЕННЯ

Я намагався створити новий проект, і "шоу" справді працює як "push". Я думаю, що проблема в моєму проекті може бути тому, що я повторно використовую навігаційний контролер з таким кодом, але не знаю, як це виправити.

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.

Відповіді:


97

Так, використовуйте "Показати" замість "Натиснути"

Як я можу зробити так, щоб "шоу" працювало як "push"? Чи можливо це чи потрібно використовувати "push (depricated)" замість цього?

Це повинно; це робить для мене. Я використовую Xcode 6 beta 2, і для тестування я використовував шаблон єдиного перегляду (виклик попередньо зробленого контролера перегляду в IB "VC_A"). Потім я додав ще один контролер перегляду ("VC_B"). Потім я додав кнопку VC_A, щоб показати VC_B та ще одну з VC_B назад до VC_A. Коли я додаю навігаційний контролер як початковий контролер перегляду в дошці та перетворюю VC_A на rootViewController, і "push", і "show" мають однаковий ефект. Якщо у мене немає початкового контролера навігації, і я використовую 'show', я отримую те, що ви описали в тому, що VC_B робить ковзання знизу. Якщо я намагаюся "натиснути", я отримую аварію, оскільки для того, щоб натиснути, я повинен мати контролер навігації.

Де я можу знайти будь-яку інформацію про нові типи segue?

Тож я знайшов деяку інформацію в сесії "Що нового у програмі створення інтерфейсів" тут . Якщо ви подивитесь на слайди, ви побачите один слайд (41), який згадує про зміну. Переглядаючи відео сеансу, ви можете перейти до хвилини 38:00, коли вони починають говорити про адаптаційні мотиви. Вони пояснюють, що, наприклад, адаптивний сег "показати", враховує контекст при вирішенні питання про те, як зробити презентацію нового контролера перегляду.


Спасибі за вашу відповідь. Я спробував створити новий проект, і "шоу" справді працює як натиснення з навігаційним контролером. У своєму проекті я має складну структуру з бічною панеллю цього уроку appcoda.com/ios-programming-sidebar-navigation-menu та push твори, шоу не робить. Це може бути причиною того, що я повторно використовую навігаційний контролер. Я оновив своє запитання кодом повторного використання.
Джон Какон

Отже, перше, що я бачу, дивлячись на ваше оновлення, - це те, що ви використовуєте очікуваний користувацький segue: "SWRevealViewControllerSegue", так що так, мабуть, не має сенсу використовувати "show" або "push" у вашому випадку, оскільки ті вбудовані виходить, тоді як ви хочете запустити власний власний код. Коли я завантажую зразок проекту, він навіть показує вибір 'custom' на seges у файлі розкадрівки.
Спенсер Холл

Я не мав на увазі цей сейф. Я говорив про створення нового UIViewController поруч із "MainViewController" (у ньому є Навігаційний контролер, і моє "оновлення" показує лише те, як я його туди отримую) та про спроби просунути новий View у MainViewController. Скріншот сценарію Я буду вдячний, якщо ви включите "використовувати класи розмірів" у зразковому проекті, створіть NewViewController і спробуйте зробити розпал між MainViewController та NewViewController шляхом "показати". Ви побачите, про що я говорю.
Джон Какон

Це щойно зараз і принаймні для мене «шоу» діяло так само, як «штовхати».
Спенсер Холл

9
Ви можете подолати помилку, переконавшись, що всі шляхи роботи у вашому контролері перегляду мають коренем UINavigationController. Навіть якщо це означає вставити UINavigationController у вашу табло, до якого ніколи не буде доступно. Схоже, електропроводка використовується для висновку про поведінку.
Скотт Робертсон

33

Уже є прийнята відповідь, але я хотів дати трохи більше інформації, можливо, інформації, яка раніше не була доступною.

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

У документі на наступному посиланні пояснюється це та опис усіх наявних сег, старих і нових.

Додавання Segue між сценами в дошці розповідей

Якщо URL-адреса в майбутньому зміниться, це пояснення, що даються для кожного нового відома:

Показати

Представляйте вміст у деталі чи майстер-області залежно від вмісту екрана. Якщо в додатку відображається головний і детальний вигляд, вміст висувається на область деталей. Якщо додаток відображає лише головну або детальну інформацію, вміст натискається поверх поточного стека контролера перегляду.

Показати деталі

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

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

Представляйте вміст модально. Є варіанти вибору стилю презентації (UIModalPresentationStyle) та стилю переходу (UIModalTransitionStyle).

Подарунок як Поповер

Представляйте вміст як переповнений приріст до існуючого перегляду. Існує можливість вказати можливі напрямки стрілки, показаної на одному краї перегляду Popover (UIPopoverArrowDirection). Також є можливість вказати вигляд прив’язки.


24

tldr; Видаліть Segue, який не натискає правильно, і відтворіть його на дошці розкадрування, перетягнувши з UIView / UIControl до контролера перегляду цілі.

З іншими відповідями немає нічого поганого, але ця пояснює, що відбувається, як ви можете перевірити, що це відбувається, і як пом'якшити проблему в майбутньому.

Фон

У моєму випадку жоден з моїх шоу-шоу не працював, хоча я вже мав UINavigationController як мій початковий контролер перегляду (з моїм вмістом UIViewController як його root).

Чому і як ламається шоу Segue

Відображення шоу розривається, коли в ньому виникає дія, пов’язана з виразкою у джерелі розширення xml. Типовим сценарієм, що спричиняє це, може бути, якщо ви переосмислили вигляд із ручного каналу, раніше закликаного в коді. Це залишає наступні біти в XML-графіці.

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

Nota Bene Щоб переглянути рекламну дошку як xml; Клацніть правою кнопкою миші файл табло та виберіть Відкрити як> Вихідний код . Для повернення використовуйте Відкрити як> Інтерфейс Builder - Розгортка

Для розміщення будь-яких спеціальних дій під час використання segue з розгортки можна просто натиснути на ReadyForSegue та перехопити контролер подання пункту призначення та викликати будь-які методи з цього місця. У будь-якому випадку, побічний ефект для цієї маленької помилки (помилка полягає в тому, що коли ви переосмислюєте виразку, вона не є належним чином встановлена ​​в xml ~, тобто дія залишається навіть після зміни зміни segue на той, який працює з UIView (або UIControl) до контролера цільового перегляду).

На жаль, саме пряме рішення не вдається. Тож просто видалення атрибута xml для дії з Всесвітньої дошки НЕ буде вирішити проблему. Натомість потрібно просто видалити та відтворити потяг із розкадрівки.

При відтворенні розкадровки xml більше не матиме дії, пов’язаної з конкретним виразком, і Шоу буде виконуватися як Push.

Зразок Xml для правильного шоу Segue

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

Пом'якшення наслідків

Щоб запобігти рецидиву, просто потрібно дотримуватися неручних розкадрів, якщо це можливо, використовуючи PrepaForSegue, щоб додати необхідні дії на основі контролера перегляду призначення. Або якщо вам потрібно змішати та поєднувати, будьте обережні, щоб переконатися, що у ваших шоу не відображаються дії, що додаються у xml розкадрівки. Якщо ви маєте справу зі старими проектами, то вам слід приділити особливу увагу вихідному коду Storyboard, оскільки я виявив декілька проблем.


3
Через години це врятувало мене, ймовірно, ще деякі години. Ось, що я б запропонував, виходячи з сказаного: Відкрийте дошку розкадрування як вихідний код , знайдіть kind = "show" і подивіться, чи рядок містить щось на зразок action = "showDetailViewController: sender:" , якщо так, видаліть усе з дії = до завершення " . У мене справді величезна таблиця розкадрів, а пошкоджена сека не містила цього параметра дії, але інша незв’язана рядок зробила. Після того, як я видалив дію, всі адаптивні послідовності спрацювали знову, як і очікувалося. Просто видалення ураженої послідовності не стало" т робота.
Маркус

Це врятувало і мене.
Адам Бардон

1
Видалення атрибута дії в XML працювало на мого друга.
Брент Роял-Гордон

врятував і мене
Джиммі Джордж Томас

Видалений атрибут дії у файлі xml та voila, він працює. Ніколи б не знайшов проблему без цієї посади.
krizzzn

20

Як прокоментував тут Скотт Робертсон , це виглядає як помилка в iOS 7.

Здається, що в iOS 8 перехід робиться під час виконання (правильна поведінка), тоді як в iOS 7 перехід робиться під час проектування (помилка поведінки).

Найпростіший спосіб вирішити проблему - додати невикористаний навігаційний контролер до розгортки та зв’язати його так, щоб контролер перегляду, який перебуває, був частиною цього контролера навігації. Вам фактично не потрібно створювати навігаційний контролер, вам просто потрібен контролер перегляду помилок, щоб знати, що він вбудований у навігаційний контролер.

Примітка: моделювання навігаційної панелі недостатньо для цих цілей; ви дійсно повинні мати в своєму наборі навігаційний контролер.

Щоб відтворити помилку:

  1. Створіть нову рекламну дошку, яка використовує класи розмірів.
  2. Створіть два контролери подання (ніяких контролерів навігації).
  3. Зробіть так, щоб перший контролер огляду показав другий контролер виду, наприклад, через шоу (наприклад, Push), пов'язане з кнопкою.
  4. У коді покажіть перший контролер перегляду, але вбудуйте його в навігаційний контролер за допомогою initWithRootViewController:методу.
  5. Запустіть додаток на iOS 7.
  6. Торкніться кнопки, яка повинна виконувати натиск.
  7. Ви отримаєте модальний перехід замість натискання на iOS 7. На iOS 8 ви отримаєте правильну поведінку push.

введіть тут опис зображення

Щоб виправити помилку:

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

введіть тут опис зображення

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


1
Дякую, трюк з NavigationController зробив це для мене, коли я поміняв корінь NavigationControllers ViewController-Stack
Peter Pint

1
Найкраще рішення. Спасибі
Илья Голованов

13

Я знаю, що я запізнююсь на це, але хотів поділитися тим, що я дізнався. Це насправді помилка і існує і сьогодні (2014-12-18).

Я написав статтю про це тут .

Він легко відтворюється; на iOS8 буде добре працювати навіть у iOS7.x, доки ви не запхнете програмний контролер програмно в стек перед тим, як викликати Showsegue.

Якщо ви лише натискаєте на стек за допомогою з'єднань з розкадровкою, це спрацює; але, мабуть, якщо ви якось натискаєте код, то navigationControllerвластивість натиснутого UIViewControllerбуде, nilі коли ви Showйого зателефонуєте, будете вважати його модальним, оскільки немає навігації для управління стеком.

Тільки обхідне рішення поки що або не надає код (не можливо), або використовує застаріле Push.

Я подав радар (посилання на статтю). Не соромтеся подавати дублікати, сподіваючись, що Apple виправить цю проблему.


3
Це було саме моє питання, дякую! використання застарілого поштовху здається в цьому випадку менш злим рішенням.
Моше Готліб

Ще одне вирішення проблеми - додати (невикористаний) навігаційний контролер до розгортки. Див stackoverflow.com/questions/24184003 / ...
Senseful

Ні! Це відбувається тут і причина - це не програмний поштовх. У моєму випадку я виконую Showsegue, то у другому Showмодному вигляді він подається модально, Solution?
Фрейд

@Frade Ви можете зв’язати репортаж із github, де це можна відтворити? Ви працюєте на якій версії iOS?
esttorhe

приватний проект .. Це трапляється при спробі виконати (секунду) ShowviewController на iOS 7
Frade

2

У мене була така ж проблема із сегами в Xcode 7 та iOS 7.1.2. Показати segues (нова функція від iOS 8) працює як модальні segues в iOS 7, і не дозволяє вам натискати контролери перегляду в стек навігаційного контролера, коли ви визначаєте тип segue з Xcode на своїй дошці розповідей. Ось чому ваш self.navigationController поверне нуль, тому що контролер перегляду не був висунутий у стек, і ви не можете його пропустити.

Я не розумію, чому Apple не додала сповіщень про цей випадок у Xcode, коли вам потрібно, щоб ваша програма працювала на iOS 7. Вони кажуть, що метод Push застарілий, але Show не працює належним чином з iOS 7.

Що я зробив, щоб вирішити проблему:

Я створив клас MYShowSegue з .h

#import <UIKit/UIKit.h>

@interface MYShowSegue : UIStoryboardSegue

@end

І .m файл лише з одним методом виконання :

#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

Тоді вам потрібно встановити тип користувальницького типу для кожного segue у вашій сторінці розказок та вибрати для нього новий клас, у моєму випадку це був MYShowSegue.

Приклад індивідуального розслідування

Це рішення допоможе вам отримати повну підтримку ваших IOS 7 додатків, вони будуть використовувати pushViewController метод , щоб підштовхнути ваші погляди і прошивку 8,9 і т.д. ваш перехід буде працювати з новим (IOS 8) методом showViewController

Не забудьте зробити те ж саме з усіма своїми сегами у вашій Радці.


Приємне рішення - працював для мене (замість того, щоб додавати "невикористаний" навігаційний контролер ...
Laurenz Glück

1

Це все ще відбувається в iOS 10.x

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

Проблема: Необхідна функціональність - 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: відправника

<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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.