iOS. Приемы программирования — страница 19 из 124

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

Необходимо динамически загрузить веб-страницу прямо в ваше приложение для iOS.

Решение

Воспользуйтесь классом UIWebView.

Обсуждение

Веб-вид (Web View) — это окно, которое браузер Safari использует для загрузки в систему iOS информации из Сети. Класс UIWebView позволяет использовать в приложениях для iOS всю мощь Safari. Все, что вам нужно сделать, — поместить веб-вид в вашем пользовательском интерфейсе и применить один из методов загрузки:

• loadData: MIMEType: textEncodingName: baseURL: — загружает в веб-вид экземпляр класса NSData;

• loadHTMLString: baseURL: — загружает в веб-вид экземпляр класса NSString. Строка должна содержать валидный HTML-код так, чтобы ее мог обработать браузер;

• loadRequest: — загружает экземпляр класса NSURLRequest. Этот метод пригодится в тех случаях, когда вы хотите загрузить в веб-вид, расположенный в вашем приложении, удаленное содержимое, на которое указывает URL.

Рассмотрим пример. Начнем с файла реализации контроллера нашего вида:


#import «ViewController.h»


@interface ViewController ()

@property(nonatomic, strong) UIWebView *myWebView;

@end


@implementation ViewController

Теперь я хочу загрузить в веб-вид строку iOS 7 Programming Cookbook. Чтобы убедиться в том, что все работает как надо и что наш веб-вид способен отображать насыщенный (форматированный) текст, я на этом не остановлюсь и выделю слово Cookbook полужирным шрифтом, а остальной текст оставлю без изменений (рис. 1.65):

— (void)viewDidLoad{

[super viewDidLoad];


self.myWebView = [[UIWebView alloc] initWithFrame: self.view.bounds];

[self.view addSubview: self.myWebView];


NSString *htmlString = @"iOS 7 Programming Cookbook";

[self.myWebView loadHTMLString: htmlString

baseURL: nil];

}



Рис. 1.65. Загрузка форматированного текста в веб-вид

Еще один способ работы с веб-видом — загрузка в него удаленного контента, на который указывает URL. Для этого можно пользоваться методом loadRequest:. Перейдем к следующему примеру, в котором загрузим основную страницу сайта Apple в веб-вид, расположенный в нашей программе для iOS (рис. 1.66):


— (void)viewDidLoad{

[super viewDidLoad];


self.myWebView = [[UIWebView alloc] initWithFrame: self.view.bounds];

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.66. Веб-вид, в который загружена домашняя страница Apple


Может понадобиться какое-то время, прежде чем в веб-вид загрузится содержимое, которое вы туда передали. Наверное, вы заметили, что при загрузке информации в браузере Safari в левом верхнем углу экрана появляется тонкий индикатор процесса, показывающий, что ваше устройство занято загрузкой контента (рис. 1.67).


Рис. 1.67. Индикатор процесса загрузки


В iOS эта задача решается с помощью делегирования. Мы сделаем подписку на делегат веб-вида, и веб-вид будет получать уведомление всякий раз, когда делегат станет загружать контент. Когда загрузка контента завершится, мы получим от веб-вида соответствующее сообщение. Все это мы сделаем, применив свойство delegate веб-вида. Делегат веб-вида должен соответствовать протоколу UIWebViewDelegate.

Идем дальше. Теперь реализуем в контроллере нашего вида небольшой индикатор процесса. Не забывайте, что индикатор протекающего процесса уже имеется в составе приложения и мы не должны создавать его сами. Управлять этим индикатором можем с помощью метода setNetworkActivityIndicatorVisible:, относящегося к UIApplication. Итак, начнем с файла реализации контроллера вида:


@interface ViewController () 

@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 и, соответственно, может иметь одно из следующих значений:

• UIProgressViewStyleDefault — это стандартное оформление вида протекания процесса. Именно в этом стиле оформлен вид, показанный на рис. 1.68;

• UIProgressViewStyleBar — напоминает UIProgressViewStyleDefault, но предназначено для использования с видами отображения протекания процессов, добавляемыми на панель инструментов.

Экземпляр UIProgressView определяет свойство под названием progress (типа float). Это свойство сообщает системе iOS, как должна отображаться полоса в виде, отражающем протекание процесса. Значение этого свойства должно быть в диапазоне от 0 до 1.0. Если сообщается значение 0, то заполнение индикатора состояния еще не началось. Значение 1.0 соответствует 100 %-ной завершенности. Степень прогресса, показанная на рис. 1.68, составляет 0.5 (или 50 %).

Чтобы научиться создавать виды, отражающие протекание процессов, создадим вид, похожий на тот, что приведен на рис. 2.74. Начинаем с главного — определяем свойство для вида протекания процесса:


#import «ViewController.h»


@interface ViewController ()

@property (nonatomic, strong) UIProgressView *progressView;

@end


@implementation ViewController


Далее инстанцируем объект типа UIProgressView:

— (void)viewDidLoad{


[super viewDidLoad];


self.progressView = [[UIProgressView alloc]

initWithProgressViewStyle: UIProgressViewStyleBar];

self.progressView.center = self.view.center;

self.progressView.progress = 20.0f / 30.0f;


[self.view addSubview: self.progressView];


}


Итак, создать вид протекания процесса совсем не сложно. В сущности, нужно просто правильно отобразить ход процесса, так как свойство progress данного вида должно иметь значение в диапазоне от 0 до 1.0, то есть нормализованное значение. Итак, если вам предстоит решить 30 задач и вы уже выполнили 20 из них, то нужно присвоить свойству progress вида протекания процесса результат следующего равенства:


self.progressView.progress = 20.0f / 30.0f;

Значения 20 и 30 передаются данному равенству как значения с плавающей точкой, поскольку компилятору нужно сообщить, что операция деления будет производиться над числами с плавающей точкой и в результате деления получится десятичная дробь. Если приказать компилятору поместить в свойстве progress вида протекания процесса целочисленное деление 20/30, то вы получите целочисленный результат 0. Это происходит потому, что компилятор выполняет целочисленное деление, отсекая полученный результат до ближайшего предшествующего целого числа. Короче говоря, на индикаторе протекания действия прогресс все время будет оставаться нулевым, пока процесс не завершится и частное от деления 30/30 не станет равно 1. Пользователю такой индикатор загрузки будет ни к чему.

1.26. Создание и отображение текстов с оформлением