Разработка iPhone/iPod touch приложений: Использования индикатора загрузки UIActivityIndicatorView.
Очень многим приложениям требуется загружать данные с удаленного сервера или использовать операции, которые занимают много времени. В таком случае пользователю нужно сообщать о длительных операциях и ставить индикатор загрузки. Это можно сделать с помощью визуального компонентаUIActivityIndicatorView. В этой статье я покажу несколько примеров его использования.
Для наглядности будет создано приложение с несколькими кнопками, каждая из которых будет показывать свой вариант использования индикатора загрузки UIActivityIndicatorView.
Я создал View-Based Application и назвал его Activity. Весь код, который будет описан ниже находиться в файлах ActivityViewController.h или ActivityViewController.m.
Первое что нужно описать это загрузка приложения и получения данных от сервера. В большинстве случаев первое, что видит пользователь, это Splash Screen. На нем нельзя размещать компоненты, это просто изображение. Но когда приложение уже загрузило свои компоненты, можно добавить индикатор загрузки и сделать подключение к серверу. Для того, что бы приложение показало Splash Screen, нужно положить в ресурсы файл Default.png.

Splash Screen
Мы можем сделать UIView с таким же фоном как Splash, добавить к нему индикатор загрузки и спокойно работать с сервером. Выглядеть это будет хорошо и для пользователя понятно. В Interface Builder этот UIView имеет такую структуру:

Структура первого UIView после Splash Screen
Установим этот UIView как главный UIView нашего контроллера и первое что увидит пользователь после Splash Screen будет индикатор загрузки с пояснением что происходит. Для того что бы показать Splash Screen подольше, можно продлить процесс загрузки компонентов из nib файла. Для этого в методе viewDidLoad пишем следующий код:
- (void)viewDidLoad {
[super viewDidLoad];
[NSThread sleepForTimeInterval:2];
[self performSelector:@selector(showAppView:) withObject:nil afterDelay:2.0f];
}
Где sleepForTimeInterval продлевает загрузку компонентов на 2 секунды, тем самым Splash виден на 2 секунды дольше. А в функции showAppView покажет нужный UIView с кнопками. Итак, окно с индикатором после показа Splash Screen будет выглядеть так:

Загрузка приложения
Итак, переходим к нашему главному View. В контроллере нужно объявить главный UIView приложения, у меня это свойство appView, а также обработчики нажатия для 5 кнопок. В .h файле это будет выглядеть так:
@interface ActivityViewController : UIViewController <UIActionSheetDelegate> {
IBOutlet UIView *appView;
}
@property (nonatomic, retain) UIView *appView;
-(IBAction) onFirstButtonClick:(id)sender;
-(IBAction) onSecondButtonClick:(id)sender;
-(IBAction) onThirdButtonClick:(id)sender;
-(IBAction) onFourthButtonClick:(id)sender;
-(IBAction) onFifthButtonClick:(id)sender;
@end
и Connection Inspector в Interface Builder

Главный UIView приложения
Все подготовлено, теперь можно переходить к написанию основного кода.
Первый пример с использованием UIActionSheet.
Основным требованиям при операциях является блокировка любых действий пользователя. Первый пример использования будет основан на UIActionSheet. В таком случае нам нужно имплементировать <UIActionSheetDelegate> в наш контроллер. Это поможет нам обрабатывать события нажатия на кнопки (если такие добавить). Мы же будем его использовать в самом простом варианте, добавим текст, сообщающий пользователю что происходит и индикатор с анимацией загрузки. Что бы показать такой индикатор нужно создать UIActivityIndicatorView, и добавить его в UIActionSheet. Пример как это сделать приведен ниже.
-(IBAction) onFirstButtonClick:(id)sender{ UIActivityIndicatorView *progressView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(-12.4, -10, 25, 25)]; progressView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; progressView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"First activity example" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil ]; [actionSheet addSubview:progressView]; [actionSheet showInView:self.view]; [actionSheet setBounds:CGRectMake(0,0,320, 100)]; [progressView startAnimating]; [self performSelector:@selector(showFirstActivity:) withObject:actionSheet afterDelay:0.1f]; [progressView release]; } -(void) showFirstActivity:(id)sender{ [NSThread sleepForTimeInterval:2]; UIActionSheet *actionSheet = (UIActionSheet *)sender; [actionSheet dismissWithClickedButtonIndex:0 animated:YES]; [actionSheet release]; }
Как видно из примера мы не добавили ни одной кнопки. Если это сделать, то для обработки нажатия потребуется более сложный вызов метода showFirstActivity. Думаю для программиста разобраться в первых строчках не составит труда. Немного поясню что мы сделали в последних строчках. При вызове метода showFirstActivity без задержки мы не получим анимацию UIActivityIndicatorView. Поэтому приложению нужно давать немного времени и вызывать этот метод с задержкой.
И вот что мы увидим на экране в результате:

Использование UIActionSheet
При таком подходе нам не нужно беспокоиться о том, что пользователь будет дальше генерировать события. UIActionSheet блокирует все нажатия до вызова у него метода dismissWithClickedButtonIndex.
Второй пример с использованием UIAlertView.
В UIAlertView можно добавлять subView. Такую возможность можно использовать для отображения индикатора. Для этого нам нужно создать UIAlertView без кнопок и добавить в него UIActivityIndicatorView. Для этого можно использовать метод addSubView.
-(IBAction) onSecondButtonClick:(id)sender{
UIAlertView *progressAlert = [[UIAlertView alloc] initWithTitle: @"Second activity example"
message: @"Please wait..."
delegate: self
cancelButtonTitle: nil
otherButtonTitles: nil];
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
activityView.frame = CGRectMake(139.0f-18.0f, 80.0f, 37.0f, 37.0f);
[progressAlert addSubview:activityView];
[activityView startAnimating];
[self performSelector:@selector(hideAlert:) withObject:progressAlert afterDelay:2.1f];
[progressAlert show];
[progressAlert release];
}
-(void) hideAlert:(id)sender{
[(UIAlertView *)sender dismissWithClickedButtonIndex:0 animated:YES];
}
Убрать UIAlertView можно вызвав у него метод dismissWithClickedButtonIndex. На экране это будет так:

Использование UIAlertView
Третий пример – использования полупрозрачный UIView
Для этого нам нужно к основному view добавить полупрозрачный UIView с размерами экрана. В этот UIView можно положить UIActivityIndicatorView.
-(IBAction) onThirdButtonClick:(id)sender{
UIView *thirdView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
UIColor *color = [[UIColor alloc] initWithWhite:0.5f alpha:0.5f];
[thirdView setBackgroundColor:color];
[color release];
UIActivityIndicatorView *progressView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(145, 215, 25, 25)];
progressView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
progressView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
[progressView startAnimating];
[thirdView addSubview:progressView];
[self.view addSubview:thirdView];
[progressView release];
[self performSelector:@selector(hideThirdView:) withObject:thirdView afterDelay:2.1f];
}
-(void) hideThirdView:(id)sender{
UIView *thirdView = (UIView *)sender;
[thirdView removeFromSuperview];
[thirdView release];
}
После завершения работы нужно убрать этот UIView с экрана методом removeFromSuperview.

Полупрозрачный UIView
Четвертый пример. Блокировка нажатий
Можно размещать UIActivityIndicatorView в любом месте на экране, но сделать блокировку нажатий. Об этом уже писал Павел Тайкало в статье Разработка iPhone/iPod touch приложений: Отключение touch событий. Код наведен ниже:
-(IBAction) onFourthButtonClick:(id)sender{
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
UIActivityIndicatorView *progressView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(145, 285, 25, 25)];
progressView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
progressView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
[self.view addSubview:progressView];
[progressView startAnimating];
[self performSelector:@selector(hideFourthView:) withObject:progressView afterDelay:2.1f];
}
-(void) hideFourthView:(id)sender{
UIActivityIndicatorView *progressView = (UIActivityIndicatorView *)sender;
[progressView removeFromSuperview];
[progressView release];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
В этом примере строкой [[UIApplication sharedApplication] beginIgnoringInteractionEvents] мы отключаем реакцию на нажатия и после завершения нужного действия, снова включаем [[UIApplication sharedApplication] endIgnoringInteractionEvents];

Блокировка нажатий
Последний метод
Этот метод не документирован. Для его использования нужно добавить описания UIProgressHUD в ActivityViewController.h.
@interface UIProgressHUD : NSObject - (UIProgressHUD *) initWithWindow: (UIView*)aWindow; - (void) show: (BOOL)aShow; - (void) setText: (NSString*)aText; @end
И методы обработки:
-(IBAction) onFifthButtonClick:(id)sender{
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
id alert = [[UIProgressHUD alloc] initWithWindow:[self.view superview]];
[alert setText:@"Please wait."];
[alert show:YES];
[self performSelector:@selector(hideFifthView:) withObject:alert afterDelay:2.0];
}
- (void) hideFifthView: (id)sender
{
[sender show:NO];
[sender release];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
Получим такое изображение.

UIProgressHUD
Очень похоже на стандартные компоненты, такие как изменение громкости.
На практике можно использовать любой из этих методов. Добавить такие компоненты можно из кода и легко ими управлять. Надеюсь информация была для вас полезной.
Не заставляйте своих пользователей долго ждать :).














Разработка iPhone/iPod touch приложений: Установка Splash screen (Default.png) < Stanfy Блог
в 12:02, 29.05.2009[...] уже говорилось, в статье об индикаторах загрузки, это самый момент подменить Splash Screen, если приложение [...]