Как в XCode 4.6 создать совершенно новое приложение для iOS, объединяющее основное приложение с вкладками и контроллер навигации на одной из вкладок?

Я пытаюсь добавить контроллер навигации внутри контроллера панели вкладок в совершенно новом стиле без раскадровки (простой старый перо).

Я нашел это демо, в котором предполагается, что XCode имеет новый шаблон проекта под названием "Приложение панели вкладок". Это не так. Теперь в XCode 4.6 есть «Новое приложение с вкладками». Конечно, Apple в своей великой мудрости решила, что у меня не должно быть nib главного окна (.xib), а контроллер панели вкладок и его страницы должны быть закодированы для меня в делегате приложения, а не в новом удобном для пользователя NIB. экземпляр контроллера вкладок. Я предполагаю, что это потому, что это более гибко, и вы можете написать код, чтобы решить, какие вкладки видит пользователь, а какие нет. Если я включу раскадровки, то, думаю, я все равно смогу делать все визуально.

Меня глубоко смущает длинная и мучительная история различий версий XCode, которые влияют на действительность существующих вопросов о stackoverflow и демонстрациях в других местах в Интернете, которые ссылаются на разные версии iOS и разные версии XCode и делают предположения, характерные для версий XCode. и iOS, которые теперь, похоже, изменились, и каждый из которых опирается на разные варианты выбора содержимого вашего Main Nib File Base Name, установленного или не установленного.

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

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

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

Apple, как известно, никогда не демонстрировала эту очевидную комбинацию панели вкладок и навигационного контроллера. Или мне так сказали. И в Руководстве по человеческому интерфейсу Apple, по-видимому, говорится (или используется для утверждения?), что лучше поместить навигационный контроллер внутри панели вкладок, чем наоборот, и мой вопрос следует понимать как желание соответствовать HIG, насколько это возможно, поэтому я считаю Я спрашиваю о рекомендуемой комбинации, а не о нерекомендуемой комбинации.

Вот что я пробовал до сих пор:

  1. Пытался следовать эта запись в блоге примерно 2009 года, в которой предполагается, что в более старых версиях XCode верно то, что уже не соответствует действительности.

  2. Начиная с нового приложения с вкладками, которое XCode сгенерировал для меня, с отключенными раскадровками, у меня есть корневой файл делегата приложения .m, который он сгенерировал для меня, который, по-видимому, создает во время запуска приложения панель вкладок. Объект контроллера полностью в коде и не имеет пера главного окна. Следующий код полностью написан Apple, и мне интересно, где (как относительно новый разработчик Cocoa) я должен взломать это и разместить свои новые материалы, если я хочу изменить одну из вкладок, чтобы иметь панель навигации и связанный с ним UINavigationViewController:

-- Этот маркер помогает не спутать систему уценки stackoverflow --

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    UIViewController *viewController1, *viewController2;
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        viewController1 = [[RPDAFirstViewController alloc] initWithNibName:@"RPDAFirstViewController_iPhone" bundle:nil];
        viewController2 = [[RPDASecondViewController alloc] initWithNibName:@"RPDASecondViewController_iPhone" bundle:nil];
    } else {
        viewController1 = [[RPDAFirstViewController alloc] initWithNibName:@"RPDAFirstViewController_iPad" bundle:nil];
        viewController2 = [[RPDASecondViewController alloc] initWithNibName:@"RPDASecondViewController_iPad" bundle:nil];
    }
    self.tabBarController = [[UITabBarController alloc] init];
    self.tabBarController.viewControllers = @[viewController1, viewController2];
    self.window.rootViewController = self.tabBarController;
    [self.window makeKeyAndVisible];
    return YES;
}

Теперь кажется, что то, что раньше было возможно без написания кода (согласно тому примеру 2009 года в блоге, на который я ссылался), теперь делается исключительно в коде. Я прочитал около 500 страниц «Программирование iOS 5», несколько сотен часов работал над своим первым приложением и пробовал множество демо-приложений, но я все еще относительно неопытный разработчик Cocoa/iOS, и я считаю, что часть моих путаницу во всем этом вызывает паттерн «контроллер и представление», и его правила их совмещения, как в коде, так и в nibs, мне не совсем понятны.

--

Обновление: у вас есть кодез! В интересах помощи будущим новичкам XCode-cocoa-iOS, таким как я, я сделал полное демонстрационное приложение и опубликовал его. на github здесь.

Скриншот: введите здесь описание изображения


person Warren P    schedule 22.02.2013    source источник
comment
Я также нашел эту демонстрацию, основанную на раскадровке. Я ищу подход без раскадровки, потому что мое существующее приложение, в которое мне в конечном итоге нужно добавить это, не имеет раскадровок, и я пока не хочу иметь дело с раскадровками. youtube.com/watch?v=Ab5jyXihwRM   -  person Warren P    schedule 22.02.2013


Ответы (4)


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

По сути, вы хотите создать UINavigationController с RootViewController, который вы хотите отобразить первым:

[UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:theViewControllerYouWantToDisplayFirst];

Затем просто добавьте этот контроллер в массив кнопок вкладок.

NSArray *tabs = [[NSArray alloc] 
                        initWithObjects: navController, otherTab, etc];

Затем установите вкладки, используя такой массив.

UITabBarController *rootController = [[UITabBarController alloc] init];
[rootController setViewControllers:tabs];

и добавьте его в свой контроллер вкладок в свое окно:

[self.window setRootViewController:rootController];

И это все. Мне потребовалось некоторое время, чтобы понять, как все устроено. Контроллер Tab View просто содержит кучу ViewControllers, вам просто нужно сделать один из этих контроллеров View вашим NavigationController.

person Ares    schedule 22.02.2013
comment
Это работает. Однако в полученном приложении нет изображения, отображаемого на вкладке, хотя я настроил его в theViewControllerYouWantToDisplayFirst. Или я должен действительно создать подкласс UINavigationController или иным образом установить СОБСТВЕННЫЙ заголовок или изображение UINavigationController? - person Warren P; 22.02.2013
comment
Нет, у тебя тоже нет. Вот как я настроил его в своем методе инициализации: [self.tabBarItem setImage:[UIImage imageNamed:@tabIcon]]; - person Ares; 22.02.2013
comment
Думаю, я сделал это правильно. Если вы не возражаете, бегло взгляните на демо, которое я разместил, оно может быть полезно для будущих легионов нубов, таких как я. - person Warren P; 22.02.2013
comment
Я посмотрел на это, и это выглядит хорошо для меня. Я бы удалил: navController.tabBarItem.image = [UIImage imageNamed:@navigate]; // это, однако, работает. из appDelegate, поскольку, я думаю, именно ViewController должен указать, каким должен быть его заголовок, а не делегат. Я был бы признателен за исправленный ответ, если вы думаете, что это все. - person Ares; 22.02.2013
comment
Я немного смущен. Ты говоришь убрать изображение? Или часть кода, где я указываю, что заголовок (строка) не используется, даже если он установлен. Если я уберу это изображение, значит, оно установлено неправильно. - person Warren P; 22.02.2013
comment
Только что отправил вам запрос на включение с комментариями. - person Ares; 22.02.2013
comment
Я объединил его, а затем сделал более длинный комментарий, чтобы читатели могли понять его намерение. - person Warren P; 22.02.2013

Если вы не против запустить новое приложение, чтобы освоить основы, попробуйте следующее:

Создайте приложение с вкладками (или как оно сейчас называется):

Затем выберите представление, которое вы хотите внедрить в NavigationController.

Затем перейдите в Editor -> Embed -> в NavigationController, как показано ниже:

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

Ваш результат будет выглядеть так:

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

Ваше здоровье!

person blaa    schedule 22.02.2013
comment
Это отличный ответ, основанный на раскадровке. Я бы предпочел не использовать раскадровки, но другим пользователям StackOverflow может понадобиться именно это. Пожалуйста, не переписывайте его, потому что, возможно, будущее за раскадровками, и сообщество SO предпочтет этот ответ. +1 - person Warren P; 22.02.2013
comment
Я предпочитаю не использовать их, если только не хочу сделать что-то необычное с пользовательским интерфейсом. Особенно размещение UITableView в UIView и добавление кнопок, изображений и многого другого. - person blaa; 22.02.2013
comment
Мне кажется, что приложение, имеющее 10 представлений без раскадровки, мало что выиграет от того, что я добавлю одно представление, основанное на раскадровке. - person Warren P; 22.02.2013

Как объяснено в первых двух ответах (оба правильные), я добавляю еще один метод, чтобы вернуться к исходному шаблону «Приложение с вкладками» (может быть, версия 3 XCode? Я не помню). В этом шаблоне у вас будет основной xib-файл, внутри которого находится ваш TabBarController.

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

  • Добавьте новый файл, Пользовательский интерфейс, Приложение Xib. В этом уроке я предполагаю, что вы назовете его «Application.xib».
  • Перейдите в свой файл AppDelegate.h и измените эту строку:

    @property (сильное, неатомарное) UIWindow *window;

добавление IBOutlet:

@property (strong, nonatomic) IBOutlet UIWindow *window;
  • Зайдите внутрь AppDelegate.m и измените свой метод applicationDidFinishLaunching с помощью этого

:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // delete all and leave only the return
    return YES;
}
  • Зайдите внутрь Application.xib, выберите «Делегат приложения» в меню «Объекты», а затем в инспекторе удостоверений измените класс -> напишите AppDelegate (или имя вашего класса AppDelegate.h)
  • Всегда в Application.xib щелкните правой кнопкой мыши еще раз на объекте делегата приложения, вы увидите выход «окно» -> свяжите его с объектом «Окно» в инспекторе объектов слева.
  • Теперь вернитесь к проекту, зайдите во вспомогательные файлы, main.m и измените строку возврата следующим образом:

:

return UIApplicationMain(argc, argv, nil, nil);
  • затем зайдите в основной файл .plist и добавьте ключ: щелкните правой кнопкой мыши, добавьте, ключ, «Базовое имя файла основного пера», введите строку, значение «Приложение» (без кавычек, без расширения .xib)

Хорошо, теперь у вас есть пустое приложение nib "старого стиля". Теперь вы можете снова войти в Application.xib, перетащить TabBar и связать его как «контроллер корневого представления» окна (щелкните правой кнопкой мыши на окне, свяжите свойство контроллера корневого представления). Затем внутри панели вкладок вы можете перетаскивать ViewControllers, контроллеры навигации и т. д.

Если вам нужны другие детали или изображения, напишите мне

РЕДАКТИРОВАТЬ:

Я загрузил пример проекта, если вы хотите посмотреть: http://www.lombax.it/documents/ManualTab.zip

Скриншот: введите здесь описание изображения

person LombaX    schedule 22.02.2013
comment
Я бы +1 вам дважды, если бы мог. Демонстрация очень хороша, потому что проще взять образец работающего кода и разобрать его на части, чем сделать интуитивный скачок от описания чего-либо к возможности его написать. (С другой стороны, именно интуитивные переходы от слов к коду показывают, что вы действительно понимаете предмет, и именно здесь я нахожусь еще на ранней стадии обучения.) - person Warren P; 22.02.2013
comment
Я загрузил скриншот, потому что думаю, что он поможет людям, которым нужно увидеть, о чем мы говорим, чтобы понять это. - person Warren P; 22.02.2013

У меня было рабочее приложение, которое я хотел поместить под одну «ногу» приложения с вкладками. Я хотел разработать другие части «большого приложения» на других вкладках. Я не хотел использовать раскадровки. Это удалило много решений, которые я нашел. Большинство оставшихся решений были разработаны с использованием более старых версий Xcode, и они просто не будут работать с версией Xcode, которую я скачал в феврале 2013 года.

Я попытался создать свое собственное приложение с вкладками (начиная с «Пустое приложение»), как это использовали некоторые разработчики в этой теме. Я чувствовал, что приближаюсь, но просто не мог заставить его работать.

Существует отличный учебник по использованию «Приложения с вкладками с контроллером навигации» Вишала Курупа.

С небольшой модификацией (перечисленной ниже), следуя видео, я смог поместить свое существующее приложение в «Приложение с вкладками» по умолчанию, созданное Xcode.

Создайте контроллер TabBar с контроллером навигации + подробное представление в Xcode 4.3

можно найти в

http://www.youtube.com/watch?v=UMpNbCs4mr4

единственное реальное изменение, которое мне пришлось внести по сравнению с «Приложением с вкладками» по умолчанию, было в AppDelegate.m:

следующий код, предоставленный при выборе «Приложения с вкладками», не будет служить моей цели

    self.tabBarController.viewControllers = @[viewController1, viewController2];

это сделал

 self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigation ,
     viewController1 ,viewController2, viewController3, viewController4,  nil];

Большое спасибо мистеру Вишалу Курупу. Он снял несколько качественных видеороликов о разработке для iOS.

person user2117002    schedule 06.05.2013