Рис. 1.57. Кнопка Delete Account (Удалить учетную запись)
 
   Кнопка может присваивать действия различным инициаторам (триггерам). Например, кнопка может производить одно действие, когда пользователь нажимает ее пальцем, и другое – когда убирает с нее палец. Эти движения становятся действиями, а объекты, реализующие действия, – их целями. Определим кнопку в файле реализации контроллера нашего вида:
 
   #import "ViewController.h"
 
   @interface ViewController ()
   @property (nonatomic, strong) UIButton *myButton;
   @end
 
   @implementation ViewController
   По умолчанию высота UIButton в iOS 7 указывается как 44.0f пункта.
   Теперь переходим к реализации кнопки (рис. 1.58):
 
   – (void) buttonIsPressed:(UIButton *)paramSender{
   NSLog(@"Button is pressed.");
   }
 
   – (void) buttonIsTapped:(UIButton *)paramSender{
   NSLog(@"Button is tapped.");
   }
 
   – (void)viewDidLoad{
   [super viewDidLoad];
 
   self.myButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
 
   self.myButton.frame = CGRectMake(110.0f,
   200.0f,
   100.0f,
   44.0f);
 
   [self.myButton setTitle:@"Press Me"
   forState: UIControlStateNormal];
 
   [self.myButton setTitle:@"I'm Pressed"
   forState: UIControlStateHighlighted];
 
   [self.myButton addTarget: self
   action:@selector(buttonIsPressed:)
   forControlEvents: UIControlEventTouchDown];
 
   [self.myButton addTarget: self
   action:@selector(buttonIsTapped:)
   forControlEvents: UIControlEventTouchUpInside];
 
   [self.view addSubview: self.myButton];
 
   }
 
   Рис. 1.58. В центре экрана находится системная кнопка
 
   В коде из данного примера мы применяем метод setTitle: forState: кнопки, задавая для нее два разных заголовка. Заголовок – это надпись на кнопке. В разное время кнопка может находиться в различных состояниях: обычном и утопленном (нажатом). В каждом из состояний надпись на ней может меняться. Например, в данном случае, когда пользователь впервые видит кнопку, на ней будет написано Press Me (Нажми меня). А когда он нажмет ее, надпись на кнопке изменится на I'm Pressed (Я нажата).
   Аналогичная ситуация складывается и с действиями, инициируемыми кнопкой. Мы используем метод addTarget: action: forControlEvents:, чтобы указать для нашей кнопки два действия:
   • действие, инициируемое, когда пользователь нажимает кнопку;
   • другое действие, происходящее, когда пользователь уже нажал кнопку и убирает палец с экрана. Такое событие называется окончанием нажатия кнопки (touch-inside-up).
   Еще одна вещь, которую необходимо знать о UIButton, заключается в том, что кнопке обязательно должен быть присвоен тип. Присваивание выполняется путем вызова метода класса buttonWithType на этапе инициализации, как показано в приведенном коде-примере. В качестве параметра этого метода передайте значение типа UIButtonType:
 
   typedef NS_ENUM(NSInteger, UIButtonType) {
   UIButtonTypeCustom = 0,
   UIButtonTypeSystem NS_ENUM_AVAILABLE_IOS(7_0),
   UIButtonTypeRoundedRect,
   UIButtonTypeDetailDisclosure,
   UIButtonTypeInfoLight,
   UIButtonTypeInfoDark,
   UIButtonTypeContactAdd,
   UIButtonTypeRoundedRect = UIButtonTypeSystem,
   }
 
   Кроме того, на кнопке может находиться изображение, которое заменяет ее стандартный внешний вид. Если у вас есть изображение или серия изображений, которые вы хотите присвоить различным состояниям кнопки, убедитесь, что кнопка относится к типу UIButtonTypeCustom. Здесь я подготовил два изображения: одно для обычного состояния кнопки, а другое – для нажатого (утопленного). Сейчас я создам кнопку и присвою ей два этих изображения:
 
   UIImage *normalImage = [UIImage imageNamed:@"NormalBlueButton.png"];
   UIImage *highlightedImage = [UIImage imageNamed:@"HighlightedBlueButton"];
 
   self.myButton = [UIButton buttonWithType: UIButtonTypeCustom];
 
   self.myButton.frame = CGRectMake(110.0f,
   200.0f,
   100.0f,
   44.0f);
 
   [self.myButton setBackgroundImage: normalImage
   forState: UIControlStateNormal];
   [self.myButton setTitle:@"Normal"
   forState: UIControlStateNormal];
 
   [self.myButton setBackgroundImage: highlightedImage
   forState: UIControlStateHighlighted];
   [self.myButton setTitle:@"Pressed"
   forState: UIControlStateHighlighted];
 
   На рис. 1.59 показано, как выглядит приложение, если его запустить в эмуляторе iOS. Чтобы задать фоновое изображение, мы используем относящийся к кнопке метод setBackgroundImage: forState:. Работая с фоновым изображением, мы можем пользоваться методами setTitle: forState: для отображения текста поверх фонового изображения. Если ваше изображение содержит текст и, таким образом, никакой надписи на кнопке не требуется, можете воспользоваться методом setImage: forState: или просто удалить заголовки с кнопки.
 
   Рис. 1.59. Кнопка с фоновым изображением

http://www.apple.com"];
   NSURLRequest *request = [NSURLRequest requestWithURL: url];
 
   [self.myWebView loadRequest: request];
   }
 
   Рис. 1.66. Веб-вид, в который загружена домашняя страница Apple
 
   Может понадобиться какое-то время, прежде чем в веб-вид загрузится содержимое, которое вы туда передали. Наверное, вы заметили, что при загрузке информации в браузере Safari в левом верхнем углу экрана появляется тонкий индикатор процесса, показывающий, что ваше устройство занято загрузкой контента (рис. 1.67).
 
   Рис. 1.67. Индикатор процесса загрузки
 
   В iOS эта задача решается с помощью делегирования. Мы сделаем подписку на делегат веб-вида, и веб-вид будет получать уведомление всякий раз, когда делегат станет загружать контент. Когда загрузка контента завершится, мы получим от веб-вида соответствующее сообщение. Все это мы сделаем, применив свойство delegate веб-вида. Делегат веб-вида должен соответствовать протоколу UIWebViewDelegate.
   Идем дальше. Теперь реализуем в контроллере нашего вида небольшой индикатор процесса. Не забывайте, что индикатор протекающего процесса уже имеется в составе приложения и мы не должны создавать его сами. Управлять этим индикатором можем с помощью метода setNetworkActivityIndicatorVisible:, относящегося к UIApplication. Итак, начнем с файла реализации контроллера вида:
 
   @interface ViewController () <UIWebViewDelegate>
   @property(nonatomic, strong) UIWebView *myWebView;
   @end
 
   @implementation ViewController
   Потом перейдем к реализации. Здесь мы будем использовать три метода из тех, которые объявляются в протоколе UIWebViewDelegate:
   • webViewDidStartLoad: – вызывается, как только вид начинает загрузку содержимого;
   • webViewDidFinishLoad: – вызывается, как только вид заканчивает загрузку содержимого;
   • webView: didFailLoadWithError: – вызывается, как только вид останавливает загрузку содержимого, например, из-за возникшей ошибки или разрыва сетевого соединения:
   – (void)webViewDidStartLoad:(UIWebView *)webView{
   [[UIApplication sharedApplication]
   setNetworkActivityIndicatorVisible: YES];
   }
 
   – (void)webViewDidFinishLoad:(UIWebView *)webView{
   [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: NO];
   }
 
   – (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
   [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible: NO];
   }
 
   – (void)viewDidLoad{
   [super viewDidLoad];
 
   self.myWebView = [[UIWebView alloc] initWithFrame: self.view.bounds];
   self.myWebView.delegate = self;
   self.myWebView.scalesPageToFit = YES;
   [self.view addSubview: self.myWebView];
 
   NSURL *url = [NSURL URLWithString:@"http://www.apple.com"];
   NSURLRequest *request = [NSURLRequest requestWithURL: url];
 
   [self.myWebView loadRequest: request];
 
   }

1.25. Отображение протекания процессов с помощью UIProgressView

Постановка задачи

   Необходимо отображать на экране индикатор протекания процесса (Progress Bar), отражающий ход выполнения той или иной задачи, например индикатор загрузки файла, скачиваемого c определенного URL.

Решение

   Инстанцируйте вид типа UIProgressView и разместите его в другом виде.

Обсуждение

   Вид протекания процесса программисты обычно называют прогресс-баром. Образец такого вида показан на рис. 1.68.
 
   Рис. 1.68. Простой вид с индикатором протекания процесса
 
   Виды, отображающие протекание процессов, обычно демонстрируются пользователю для показа выполнения задачи с четко определенными начальной и конечной точками. Примером такой задачи является, например, скачивание 30 файлов. Очевидно, что такая задача будет выполнена, когда все 30 файлов будут скопированы на устройство. Вид, отображающий протекание процесса, является экземпляром UIProgressView и инициализируется с помощью специального метода-инициализатора данного класса – initWithProgressViewStyle:. В качестве параметра данный метод принимает стиль (оформление) панели протекания, которую предполагается создать. Этот параметр относится к типу UIProgressViewStyle и, соответственно, может иметь одно из следующих значений: