Как использовать UIProgressView при загрузке UIWebView?

Я разрабатываю приложение, в котором я загружаю urlrequest в UIWebView, и это произошло успешно.

Но теперь я пытаюсь отобразить UIProgressView во время загрузки (начиная с 0,0 до 1,0), который динамически изменяется по мере загрузки.

Как я могу это сделать?


person raaz    schedule 14.12.2009    source источник


Ответы (3)


UIWebView не дает вам никакой информации о ходе выполнения в обычном режиме. Что вам нужно сделать, это сначала получить данные асинхронно с помощью NSURLConnection. Когда используется метод делегата NSURLConnection connection:didReceiveResponse, вы собираетесь взять число, полученное от expectedContentLength, и использовать его в качестве максимального значения. Затем внутри метода делегата connection:didReceiveData вы собираетесь использовать свойство length экземпляра NSData, чтобы сообщить вам, как далеко вы продвинулись, поэтому ваша доля прогресса будет length / maxLength, нормализованная до значений от 0,0 до 1,0.

Наконец, вы собираетесь инициировать веб-просмотр с данными вместо URL-адреса (в вашем connection:didFinishLoading методе делегата).

Два предостережения:

  1. Возможно, что свойство expectedContentLength NSURLResponse будет -1 (константа NSURLReponseUnknownLength). В этом случае я бы посоветовал запустить стандартный UIActivityIndicator, который вы отключаете внутри connection:didFinishLoading.

  2. Убедитесь, что каждый раз, когда вы манипулируете видимым элементом управления из одного из методов делегата NSURLConnection, вы делаете это, вызывая performSelectorOnMainThread: - иначе вы начнете получать ужасные ошибки EXC_BAD_ACCESS.

Используя эту технику, вы можете показать индикатор выполнения, если вы знаете, сколько данных вам нужно получить, и счетчик, если не знаете.

person Kevin Hoffman    schedule 15.12.2009
comment
Проблема с реализацией выборки данных NSURLConnection поверх запроса загрузки UIWebView заключается в том, что вы получаете одни и те же данные дважды, что является расточительным для облегченного соединения. Вы можете загрузить экземпляр NSData непосредственно в UIWebView с помощью loadData:MIMEType:textEncodingName:baseURL:, но это может поставить под угрозу другие аспекты использования UIWebView. - person ; 24.04.2012

Вы можете попробовать использовать этот подкласс UIWebView, который использует частные методы UIWebView - следовательно, это решение не на 100% безопасно для AppStore (хотя некоторые приложения используют его почти на 100%: Facebook, приложение Google, ...).

https://github.com/petr-inmite/imtwebview

person joshis    schedule 23.11.2011

Используя NSURLConnection, вы дважды получаете одни и те же данные, тратя время, потому что это может замедлить взаимодействие с пользователем, он загружает данные дважды, потребляет интернет-данные. Лучше сделать uiprogress на основе таймера и при успешной загрузке веб-просмотра веб-страница будет показывать загрузку uiprogress. В этом случае вы можете показывать динамический uiprogress каждый раз, когда загружается веб-страница .. не забудьте создать представление uiprogress, назвав его myProgressview и установить его в файле владельца.

ВОТ КОД, НАДЕЖДА, ПОМОГАЕТ

@synthesize myProgressView;
- (void)updateProgress:(NSTimer *)sender
{      //if the progress view is = 100% the progress stop
    if(myProgressView.progress==1.0)
    {
        [timer invalidate]; 
    }
   else
         //if the progress view is< 100% the progress increases
       myProgressView.progress+=0.5;
}
- (void)viewDidLoad
{ //this is the code used in order to load the site
    [super viewDidLoad];
    NSString *urlAddress = @"http://www.playbuzz.org/";
    myWebview.delegate = self;
   [myWebview loadRequest:[NSURLRequest requestWithURL:[NSURL     URLWithString:urlAddress]]];
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{    ///timer for the progress view

 timer=[[NSTimer scheduledTimerWithTimeInterval:0.1
                          target:self
                          selector:@selector(updateProgress:)
                          userInfo:myProgressView
                          repeats:YES]retain];

}

- (void)dealloc {
    [myProgressView release];
    [super dealloc];
}
@end

этот код и идея действительно помогают мне в решении моей проблемы.

person Cristiana Chavez    schedule 04.10.2013