Как проще всего создать статическую библиотеку iOS, которая имеет собственный модальный интерфейс? - PullRequest
5 голосов
/ 06 июля 2011

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

Грубая архитектура

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

Я вижу два способа сделать это.

Вариант 1

Когда приложение хочет, чтобы библиотека показывала свой пользовательский интерфейс, AppDelegate передает self.window, и библиотека устанавливает собственный контроллер корневого представления, фактически получая полное владение пользовательским интерфейсом. Когда пользовательский интерфейс завершен, он уведомляет AppDelegate, который затем устанавливает собственный корневой контроллер представления в окне, возвращая право владения пользовательским интерфейсом.

Вариант 2

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

Вопросы

При использовании опции 1 могут возникнуть проблемы при смене контроллеров корневых представлений во время работы приложения. При выборе варианта 2 могут возникнуть проблемы с предоставлением контроллера представления, который может работать в произвольном контексте (в качестве контроллера полноэкранного представления, в качестве дополнительного представления UINavigationController и т. Д.).

Другая проблема с обоими вариантами - это другие уведомления UIApplicationDelegate, которые может получать AppDelegate, например applicationWillResignActive: и applicationDidBecomeActive :. Библиотеке может потребоваться обрабатывать подобные уведомления, чтобы должным образом поддерживать свой пользовательский интерфейс. Должен ли AppDelegate передавать каждый из них в библиотеку, когда его пользовательский интерфейс активен?

Есть ли лучший вариант 3, о котором я не подумал?

Ответы [ 3 ]

5 голосов
/ 15 июля 2011

Рассматривали ли вы разработку своего API для принятия UIViewController:

- (void)presentFromViewController:(UIViewController *)presentingViewController
                         animated:(BOOL)animated
{
    [presentingViewController presentModalViewController:myViewController
                                                animated:animated];
}

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

Не беспокойтесь о том, чтобы обойти -applicationWillResignActive: и т. д. Просто зарегистрируйтесь для получения базовых уведомлений UIApplicationWillResignActiveNotification и т. д. в своем классе библиотеки.

3 голосов
/ 16 июля 2011

Вот как я это делаю: В вашей статической библиотеке создайте свой UIViewController и все представления контента, которые вам нужны программно (поскольку вы не можете легко создавать Frameworks на iOS, вы не можете легко объединять ресурсы):

UIViewController *controller = [[[UIViewController alloc] initWithNibName: nil bundle: nil] autorelease];
UIView *containerView = [[[UIView alloc] initWithFrame: [UIScreen mainScreen].applicationFrame] autorelease];
containerView.backgroundColor = [UIColor darkGrayColor];

UIWebView *webView = [[[UIWebView alloc] initWithFrame: containerView.bounds] autorelease];
webView.delegate = self;

// ... some other code to setup custom things

[containerView addSubview: webView];

// ... some other code to setup custom things, spinner etc.

затем отобразите его с помощью

[[UIApplication sharedApplication].keyWindow.rootViewController presentModalViewController: myViewController animated: YES];

Это вырезано и вставлено из рабочей статической библиотеки, которая была встроена в два разных приложения iOS и, кажется, хорошо работает в обоих. Могут быть крайние случаи, которые это не покрывает, но я еще не поразил их:)

1 голос
/ 12 июля 2011

Использовать блоки вместо делегата.Ваше представление должно вызвать предоставленное dismissBlock, сохраненное в свойстве, когда оно выполнено, и вызывающий может сделать то, что ему нужно сделать, из этого блока.У вас есть данные, которые нужно передать обратно?Сделайте это аргументом блока или поместите его в свойство объекта, доступного из вашего контроллера представления, в зависимости от ситуации.

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

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

...