sábado, 2 de junio de 2012

Indicador de actividad

Una de las cosas que se debe evitar por todos los medios cuando se está desarrollando una App es que la ventana se quede bloqueada y no se muestre algún indicador que informe que está trabajando. Por ejemplo cuando se está cargando una página web. 
Una solución para evitar esta situación tan frustrante para el usuario es utilizar la propiedad setNetworkActivityIndicatorVisible de la clase UIApplication. Con esto se consigue añadir el circulo con rayitas que van cambiado de tono en la parte superior de la aplicación:


Otra posible forma sería utilizar la clase UIActivityIndicatorView. Vamos a ver un sencillo en el que mostraremos estos dos tipos de indicadores mientras se carga una página web.

Crearemos un Story Board con un View Controller al que añadiremos un Web View. Además cablearemos este UIWebView hacía el controller para especificarlo como su delegate. A continuación lo metemos en un Navigation Controller.


Network Activity Indicator


El interface del View Controller será así:

#import <UIKit/UIKit.h>

@interface WebViewController : UIViewController <UIWebViewDelegate>
@property (nonatomic, weak) NSString *webPage;
@property (weak, nonatomic) IBOutlet UIWebView *webView;

@end


Como veis el modelo va a ser un string con la URL. Además hemos añadido el protocolo UIWebViewDelegate.

El UIWebView lo voy a definir como local:

@interface WebViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end


La implementación de viewDidLoad será así:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Cargamos la página web en el web view
    NSURL *url = [NSURL URLWithString:self.webPage];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:requestObj];
}

Y se necesita añadir dos métodos del UIWebViewDelegate:
  •  webViewDidStartLoad: indica cuando comienza a cargarse la página web. Es en ese momento cuando se debe poner la propiedad NetworkActivityIndicator a YES.
  • webViewDidFinishLoad: indica cuando termina de cargarse la página web. Se pondrá NetworkActivityIndicator a NO.

- (void)webViewDidStartLoad:(UIWebView *)webView {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}


Activity Indicator View

Añadiremos una propiedad local para el  UIActivityIndicatorView:

@interface  WebViewController ()
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (strong, nonatomic) UIActivityIndicatorView *activityIndicator;
@end

Y voy a definir su método set así:

- (UIActivityIndicatorView *)activityIndicator
{
    if (_activityIndicator == nil) 
    {
        _activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    }
    return _activityIndicator;
}

En este caso el viewDidLoad será: 

- (void)viewDidLoad
{
    [super viewDidLoad];
//  Con esto añadimos un botón al navigation bar con el activity indicator   
    UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:self.activityIndicator];
   [self navigationItem].rightBarButtonItem = barButton;
    
    NSURL *url = [NSURL URLWithString:self.webPage];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];

    [self.webView loadRequest:requestObj];
}

Para terminar en los métodos webViewDidStartLoad webViewDidStartLoad  empezaremos y terminaremos la animación:

- (void)webViewDidStartLoad:(UIWebView *)webView {
    [self.activityIndicator startAnimating];
}

//Called whenever the view finished loading something

- (void)webViewDidFinishLoad:(UIWebView *)webView{
   [self.activityIndicator stopAnimating];
}

El resultado de esta segunda opción será este:


En este caso el indicador de actividad se muestra en la barra del Navigation Controller.

@Fin