2009-12-14 4 views
11

sto sviluppando un'applicazione in cui sto caricando un urlrequest in UIWebView ed è successo con successo.Come utilizzare UIProgressView durante il caricamento di un UIWebView?

Ma ora sto cercando di visualizzare un UIProgressView quando il caricamento è in corso (a partire da 0.0 a 1.0), che viene modificato dinamicamente con l'avanzamento del caricamento.

Come posso farlo?

risposta

21

UIWebView non fornisce informazioni sull'avanzamento nella modalità normale. Quello che devi fare è recuperare i dati in modo asincrono usando NSURLConnection. Quando si utilizza il metodo delegato NSURLConnection connection:didReceiveResponse, si prende il numero ottenuto da expectedContentLength e lo si utilizza come valore massimo. Quindi, all'interno del metodo delegato connection:didReceiveData, utilizzerai la proprietà length dell'istanza NSData per dirti quanto sei distante, quindi la tua frazione di progresso sarà length/maxLength, normalizzata tra 0,0 e 1,0.

Infine, si avvia la visualizzazione Web con i dati anziché un URL (nel metodo connection:didFinishLoading delegato).

due accorgimenti:

  1. È possibile che la proprietà del NSURLResponse expectedContentLength sarà -1 (NSURLReponseUnknownLength costante). In tal caso, suggerirei di lanciare un UIActivityIndicator standard da chiudere all'interno di connection:didFinishLoading.

  2. Assicurarsi che ogni volta che si manipola un controllo visibile da uno dei metodi delegati NSURLConnection, lo si faccia chiamando performSelectorOnMainThread: - altrimenti inizierai a ricevere gli errori EXC_BAD_ACCESS temuti.

Utilizzando questa tecnica, è possibile visualizzare una barra di avanzamento quando si conosce la quantità di dati che si desidera ottenere e una centrifuga quando non si conosce.

+0

Il problema con l'implementazione del recupero dati NSURLConnection sulla richiesta di caricamento di UIWebView è che si stanno acquisendo gli stessi dati due volte, il che è uno spreco su una connessione leggera. È possibile caricare l'istanza NSData direttamente in UIWebView con 'loadData: MIMEType: textEncodingName: baseURL:', ma questo può compromettere altri aspetti dell'utilizzo di UIWebView. –

2

È possibile provare a utilizzare questa sottoclasse di UIWebView che utilizza i metodi UIWebView privati, pertanto questa soluzione non è sicura al 100% in AppStore (sebbene alcune app lo utilizzino quasi al 100%: Facebook, app Google, ...) .

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

-2

Utilizzando NSURLConnection stai recuperando gli stessi dati due volte, perdita di tempo, perché può rallentare l'interazione con l'utente che carica i dati due volte, consuma internet data.It è meglio fare un'uiprogress basa su timer e quando la webview ha caricato correttamente la pagina web mostrerà l'uiprogress che carica. In quel caso puoi mostrare un uiprogress dinamico ogni volta che la pagina web viene caricata .. non dimenticare di creare una vista di uiprogress e nominarla myProgressview e impostarla nel proprietario del file .

è QUI IL CODICE speriamo vi sia utile

@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 

questo codice e idea davvero mi aiuta a risolvere il mio problema.