Шрифт:
Интервал:
Закладка:
self.buttonPhoto = [UIButton buttonWithType: UIButtonTypeRoundedRect];
[self.buttonPhoto setTitle:@"Photo"
forState: UIControlStateNormal];
[self.buttonPhoto addTarget: self
action:@selector(gotoAppleWebsite:)
forControlEvents: UIControlEventTouchUpInside];
self.buttonPhoto.frame = buttonRect;
[self.view addSubview: self.buttonPhoto];
buttonRect.origin.y += 50.0f;
self.buttonAudio = [UIButton buttonWithType: UIButtonTypeRoundedRect];
[self.buttonAudio setTitle:@"Audio"
forState: UIControlStateNormal];
[self.buttonAudio addTarget: self
action:@selector(gotoAppleStoreWebsite:)
forControlEvents: UIControlEventTouchUpInside];
self.buttonAudio.frame = buttonRect;
[self.view addSubview: self.buttonAudio];
}
Теперь в методе viewDidLoad корневого контроллера вида создадим навигационную кнопку. В зависимости от типа устройства при нажатии навигационной кнопки мы будем отображать либо вспомогательный экран (на iPad), либо предупреждающий вид (на iPhone):
— (void)viewDidLoad{
[super viewDidLoad];
/* Проверяем, существует ли этот класс в том варианте iOS,
где действует приложение. */
Class popoverClass = NSClassFromString(@"UIPopoverController");
if (popoverClass!= nil &&
UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
PopoverContentViewController *content =
[[PopoverContentViewController alloc] initWithNibName: nil
bundle: nil];
self.popoverController = [[UIPopoverController alloc]
initWithContentViewController: content];
content.popoverController = self.popoverController;
self.barButtonAdd = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem: UIBarButtonSystemItemAdd
target: self
action:@selector(performAddWithPopover:)];
} else {
self.barButtonAdd = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem: UIBarButtonSystemItemAdd
target: self
action:@selector(performAddWithAlertView:)];
}
[self.navigationItem setRightBarButtonItem: self.barButtonAdd
animated: NO];
}
Контроллер вспомогательного экрана ставит на себя ссылку в контроллере информационного вида сразу после инициализации информационного вида. Это очень важно. Контроллер вспомогательного экрана невозможно инициализировать в отсутствие контроллера информационного вида. Как только контроллер вспомогательного экрана инициализирован посредством контроллера информационного вида, можно продолжать работу и изменять контроллер информационного вида в контроллере вспомогательного экрана — но этого нельзя делать в процессе инициализации.
Мы решили, что при нажатии навигационной кнопки + на устройстве iPad будет запускаться метод performAddWithPopover:. Если мы имеем дело не с iPad, то нужно, чтобы при нажатии этой кнопки запускался метод performAddWithAlertView:. Итак, реализуем два этих метода, а также позаботимся о методах делегатов предупреждающего вида — чтобы нам было известно, какую кнопку в предупреждающем виде нажимает пользователь, работающий с iPhone:
— (NSString *) photoButtonTitle{
return @"Photo";
}
— (NSString *) audioButtonTitle{
return @"Audio";
}
— (void) alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger)buttonIndex{
NSString *buttonTitle = [alertView buttonTitleAtIndex: buttonIndex];
if ([buttonTitle isEqualToString: [self photoButtonTitle]]){
/* Добавляем фотографию… */
}
else if ([buttonTitle isEqualToString: [self audioButtonTitle]]){
/* Добавляем аудио… */
}
}
— (void) performAddWithAlertView:(id)paramSender{
[[[UIAlertView alloc] initWithTitle: nil
message:@"Add…"
delegate: self
cancelButtonTitle:@"Cancel"
otherButtonTitles:
[self photoButtonTitle],
[self audioButtonTitle], nil] show];
}
— (void) performAddWithPopover:(id)paramSender{
[self.popoverController
presentPopoverFromBarButtonItem: self.barButtonAdd
permittedArrowDirections: UIPopoverArrowDirectionAny
animated: YES];
}
Если запустить это приложение в эмуляторе iPad, то при нажатии кнопки + на навигационной панели мы увидим примерно такой интерфейс, как на рис. 1.79.
Рис. 1.79. Простой вспомогательный экран, отображаемый после нажатия навигационной кнопки
Если запустить это же универсальное приложение в эмуляторе iPhone и нажать на навигационной панели кнопку +, результат будет примерно как на рис. 1.80.
Рис. 1.80. В универсальном приложении вспомогательные экраны заменяются предупреждающими видами
Здесь мы воспользовались важным свойством контроллера информационного вида: preferredContentSize. Когда вспомогательный экран отображает контроллер своего информационного вида, он будет автоматически считывать значение этого свойства и корректировать свой размер (высоту и ширину). Кроме того, мы использовали метод presentPopoverFromBarButtonItem: permittedArrowDirections: animated: вспомогательного экрана в корневом контроллере нашего вида. Этот метод нужен, чтобы вспомогательный экран отображался над кнопкой навигационной панели. Первый параметр, принимаемый данным методом, — это кнопка навигационной панели, та, над которой должен всплывать контроллер вспомогательного экрана. Второй параметр указывает при появлении вспомогательного экрана направление его развертывания относительно объекта, из которого он появляется. Например, на рис. 1.79 видно, что стрелка вспомогательного экрана указывает вверх от кнопки с навигационной панели. Значение, передаваемое этому параметру, должно относиться к типу UIPopoverArrowDirection::
typedef NS_OPTIONS(NSUInteger, UIPopoverArrowDirection) {
UIPopoverArrowDirectionUp = 1UL << 0,
UIPopoverArrowDirectionDown = 1UL << 1,
UIPopoverArrowDirectionLeft = 1UL << 2,
UIPopoverArrowDirectionRight = 1UL << 3,
UIPopoverArrowDirectionAny = UIPopoverArrowDirectionUp |
UIPopoverArrowDirectionDown |
UIPopoverArrowDirectionLeft |
UIPopoverArrowDirectionRight,
UIPopoverArrowDirectionUnknown =
NSUIntegerMax
};
См. также
Разделы 1.9 и 1.15.
Глава 2. Создание динамических и интерактивных пользовательских интерфейсов
2.0. Введение
Когда iPhone только появился на рынке, он поистине задал стандарт интерактивности в мобильных приложениях. Приложения iOS были и остаются поразительно интерактивными — вы можете на ходу манипулировать различными компонентами пользовательского интерфейса, корректируя их для максимально полного удовлетворения своих потребностей.
В iOS 7 Apple добавила в iOS SDK ряд новых классов, которые позволяют обогащать ваше приложение очень интересной физикой, делая их еще более интерактивными. Например, в новой iOS вы заметите, что фоновые рисунки, которые могут служить обоями Рабочего стола, стали еще живее, так как они могут двигаться по экрану, если вы качаете устройство влево-вправо, и т. д. Появились также новые разновидности поведений, которые iOS позволяет добавлять в приложения.
Приведу другой пример. Допустим, у вас есть приложение для обмена фотографиями, работающее на iPad. В левой части экрана находятся несколько картинок, которые были извлечены из пользовательского фотоальбома на Рабочий стол. Справа расположен компонент, напоминающий корзину. Каждая фотография, перенесенная в корзину, будет доступна для пакетного совместного использования через какую-нибудь социальную сеть, например Facebook. Вы хотите обогатить интерактивность приложения с помощью анимации так, чтобы пользователь мог «кидать» фотографии в корзину слева, а фотографии закреплялись в корзине. Все это можно было сделать и раньше, но для выполнения таких операций требовались глубокие знания Core Animation, а также довольно хорошее понимание физики.
Пользуясь UI Dynamics — новой технологией от Apple, — вы можете значительно упростить реализацию многих таких возможностей в приложении. На самом деле достаточно всего нескольких строк кода, чтобы реализовать в ваших видах очень интересную физику и необычное поведение.
Apple категоризировала такие действия в классах поведений, которые можно прикреплять к аниматору. Например, вы можете добавить к кнопке в вашем виде тяготение. В таком случае кнопка будет падать из верхней части вида (если вы ее там поместили) до самого его низа и даже сможет выпадать за его пределы. Если вы хотите этому воспрепятствовать и сделать так, чтобы кнопка падала только до дна вида и не дальше, то к аниматору нужно прикрепить и другое поведение — столкновение. Аниматор будет управлять поведениями, которые вы добавите к разным видам вашего приложения, а также их взаимодействиями. Вам не придется об этом беспокоиться. Далее перечислены несколько классов, обеспечивающих различное поведение компонентов пользовательского интерфейса:
- QT 4: программирование GUI на С++ - Жасмин Бланшет - Программирование
- Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен - Программирование
- C# для профессионалов. Том II - Симон Робинсон - Программирование
- Стандарты программирования на С++. 101 правило и рекомендация - Герб Саттер - Программирование
- Программирование игр и головоломок - Жак Арсак - Программирование
- Генерация высококачественного кода для программ, написанных на СИ - Филипп Хислей - Программирование
- Программирование на Python с нуля - Максим Кононенко - Программирование
- C# 4.0: полное руководство - Герберт Шилдт - Программирование
- Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов - Программирование
- От «Энигмы» до ChatGPT - Рустам Агамалиев - Программирование / Экономика