Шрифт:
Интервал:
Закладка:
— (void) alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger)buttonIndex{
[self activityDidFinish: YES];
}
3. Далее переопределим метод activityType нашей функции. Возвращаемое значение этого метода представляет собой объект типа NSString, являющийся уникальным идентификатором этой функции. Это значение не будет отображаться для пользователя — оно применяется только на уровне системы iOS для отслеживания идентификатора функции. Нет никаких особых значений, которые требовалось бы возвращать от этого метода, нет также никаких сопутствующих рекомендаций от Apple, но мы будем работать со строками в формате «обратное доменное имя», использовать идентификатор пакета приложения и прикреплять к нему имя нашего класса. Итак, если имеется идентификатор пакета com.pixolity.ios.cookbook.myapp и класс с именем StringReverserActivity, то мы возвратим от этого метода строку com.pixolity.ios.cookbook.myapp.StringReverserActivity, вот так:
— (NSString *) activityType{
return [[NSBundle mainBundle].bundleIdentifier
stringByAppendingFormat:@".%@", NSStringFromClass([self class])];
}
4. Следующий метод, который придется переопределить, называется activityTitle. В нем мы собираемся возвращать строку, которую будем отображать для пользователя в контроллере вида с функцией. Необходимо, чтобы эта строка получилась не слишком длинной и уместилась в нашем контроллере вида:
— (NSString *) activityTitle{
return @"Reverse String";
}
5. Переходим к методу activityImage, который должен возвращать нам экземпляр UIImage — то самое изображение, что будет выводиться в контроллере вида с функцией. Обязательно предоставляйте по два варианта изображения — для сетчаточного дисплея и для обычного — как для iPad, так и для iPhone/iPod. Разрешение сетчаточного изображения для iPad должно составлять 110 × 110 пикселов, а для iPhone — 86 × 86 пикселов. Неудивительно, что, разделив эти значения на 2, получим ширину и высоту обычных изображений. В этом изображении iOS использует только альфа-канал, поэтому убедитесь, что фон вашего изображения является прозрачным и что вы иллюстрируете его черным или белым цветом. Я уже создал изображение в разделе с ресурсами моего приложения и назвал его Reverse (Обратное). Вы можете ознакомиться с ним на рис. 1.29. А вот и код:
— (UIImage *) activityImage{
return [UIImage imageNamed:@"Reverse"];
}
Рис. 1.29. В категории Ресурсы содержатся изображения для создаваемой специальной функции
6. Реализуем метод canPerformWithActivityItems: нашей функции. Параметр этого метода содержит массив, который будет задан, когда метод-инициализатор контроллера вида с функцией получит массив компонентов функции. Не забывайте, что тип каждого из объектов данного массива является произвольным. Возвращаемое значение данного метода является логическим и указывает, можем ли мы произвести такую функцию над каждым конкретным элементом массива. Например, наша функция может обратить любое количество данных ей строк. То есть если мы найдем в массиве одну строку, это будет нам на руку, поскольку мы будем точно знать, что впоследствии сможем обратить эту строку. Но если мы получим массив из 1000 объектов, ни один из которых не будет относиться к приемлемому для нас типу, мы отклоним такой запрос, вернув NO от данного метода:
— (BOOL) canPerformWithActivityItems:(NSArray *)activityItems{
for (id object in activityItems){
if ([object isKindOfClass: [NSString class]]){
return YES;
}
}
return NO;
}
7. Теперь реализуем метод prepareWithActivityItems: нашей функции, чей параметр относится к типу NSArray. Этот метод вызывается, если вы возвращаете YES от метода canPerformWithActivityItems:. Придется сохранить данный массив для последующего использования. Но на самом деле можно сохранять не весь массив, а только часть его объектов — те, что относятся к интересующему вас типу. Например, строки:
— (void) prepareWithActivityItems:(NSArray *)activityItems{
NSMutableArray *stringObjects = [[NSMutableArray alloc] init];
for (id object in activityItems){
if ([object isKindOfClass: [NSString class]]){
[stringObjects addObject: object];
}
}
self.activityItems = [stringObjects copy];
}
8. Последнее, но немаловажное: потребуется реализовать метод performActivity нашей функции, который вызывается, если iOS требует от нас произвести выбранные действия над списком ранее предоставленных произвольных объектов. В функции мы собираемся перебрать массив строковых объектов, извлеченных из массива с произвольными типами, обратить их все и отобразить для пользователя в окне с предупреждением:
— (NSString *) reverseOfString:(NSString *)paramString{
NSMutableString *reversed = [[NSMutableString alloc]
initWithCapacity: paramString.length];
for (NSInteger counter = paramString.length — 1;
counter >= 0;
counter—){
[reversed appendFormat:@"%c", [paramString characterAtIndex: counter]];
}
return [reversed copy];
}
— (void) performActivity{
NSMutableString *reversedStrings = [[NSMutableString alloc] init];
for (NSString *string in self.activityItems){
[reversedStrings appendString: [self reverseOfString: string]];
[reversedStrings appendString:@"n"];
}
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Reversed"
message: reversedStrings
delegate: self
cancelButtonTitle:@"OK"
otherButtonTitles: nil];
[alertView show];
}
Итак, реализация класса нашей функции завершена. Перейдем к файлу реализации контроллера вида и отобразим контроллер вида функции в списке с нашей специальной функцией:
#import «ViewController.h»
#import «StringReverserActivity.h»
@implementation ViewController
— (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear: animated];
NSArray *itemsToShare = @[
@"Item 1",
@"Item 2",
@"Item 3",
];
UIActivityViewController *activity =
[[UIActivityViewController alloc]
initWithActivityItems: itemsToShare
applicationActivities:@[[StringReverserActivity new]]];
[self presentViewController: activity animated: YES completion: nil];
}
@end
При первом запуске приложения на экране появится картинка, примерно такая, как на рис. 1.30.
Рис. 1.30. Специальная функция для обращения строк теперь находится в списке доступных функций
Если теперь вы нажмете в этом списке элемент Reverse String (Обращенная строка), то увидите нечто похожее на рис. 1.31.
Рис. 1.31. Наша функция для обращения строк в действии
См. также
Раздел 1.10.
1.12. Внедрение навигации с помощью UINavigationController
Постановка задачи
Необходимо дать пользователю возможность переходить от одного контроллера вида к другому, сопровождая этот процесс плавной анимацией, интегрированной в программу.
Решение
Используйте экземпляр класса UINavigationController.
Обсуждение
Если вам доводилось работать с iPhone, iPod touch или iPad, то вы, скорее всего, уже видели в действии навигационный инструмент управления. Например, если перейти в приложение Settings (Настройки) телефона, там можно выбрать команду Wallpaper (Обои) (рис. 1.32). В таком случае вы увидите, как основной экран программы Settings (Настройки) отодвигается влево, а на его место справа выходит экран Wallpaper (Обои). В этом и заключается самая интересная черта навигации iPhone. Вы можете складывать контроллеры видов в стек и поднимать их из стека. Контроллер вида, в данный момент находящийся на верхней позиции стека, виден пользователю. Итак, только самый верхний контроллер вида показывается зрителю, а чтобы отобразить другой контроллер, нужно либо удалить с верхней позиции контроллер, видимый в настоящий момент, либо поместить на верхнюю позицию в стеке новый контроллер вида.
Рис. 1.32. Контроллер вида настроек, отодвигающий вид с обоями для экрана
Теперь добавим в новый проект навигационный контроллер. Но сначала нужно создать проект. Выполните шаги, описанные в разделе 1.9, чтобы создать пустое приложение с простым контроллером вида. Данный раздел — расширенная версия работы, выполненной в разделе 1.9. Начнем с файла реализации (.m) делегата нашего приложения:
#import «AppDelegate.h»
#import «FirstViewController.h»
@interface AppDelegate ()
@property (nonatomic, strong) UINavigationController *navigationController;
- QT 4: программирование GUI на С++ - Жасмин Бланшет - Программирование
- Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен - Программирование
- C# для профессионалов. Том II - Симон Робинсон - Программирование
- Стандарты программирования на С++. 101 правило и рекомендация - Герб Саттер - Программирование
- Программирование игр и головоломок - Жак Арсак - Программирование
- Генерация высококачественного кода для программ, написанных на СИ - Филипп Хислей - Программирование
- Программирование на Python с нуля - Максим Кононенко - Программирование
- C# 4.0: полное руководство - Герберт Шилдт - Программирование
- Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов - Программирование
- От «Энигмы» до ChatGPT - Рустам Агамалиев - Программирование / Экономика