Control de navegación: “navigation controlers”! Diseño de aplicaciones: opciones de navegación! Barra de navegación:! Barra de “tabs”:! UINavigationController! UITabBarController! Híbrido ...! 19 – Febrero de 2011! Luis Montesano, Ana C. Murillo! Pila de vistas: UINavigationController! Pila de vistas: UINavigationController! • Personalizar • Título del controlador de la vista encima de la pila.! • Título del controlador de la vista anterior! • Vista • Barra encima de la pila! de herramientas de la vista encima de la pila! barras de herramientas: UINavigationItem ! • Todos los controladores de vistas tienen un “navigationItem” para personalizar títulos, botones,... (opciones en UINavigationBar.h), se visualizan cuando ese controlador está en arriba de la pila:! • Edit/done (muy común, pre-definido) self.navigationItem.leftBarButtonItem = self.editButtonItem;! • Botones a izq. y dcha. : definir un botón y asignarlo como navigation item de la vista actual self.navigationItem.leftBarButtonItem = fooButton; self.navigationItem.rightBarButtonItem = addButton;! • Cambiar • Botón el título por algún “control”: self.navigationItem.titleView = segmentedControl;! de “volver”: por defecto escribe el título de la vista anterior. Se puede cambiar self.title = @“Hello there, CS193P!”; UIBarButtonItem *heyButton = [[UIBarButtonItem alloc] initWithTitle:@“Hey!” . . .]; self.navigationItem.backButtonItem = heyButton;! Pila de vistas: UINavigationController! Pila de vistas: UINavigationController! en "MyAppDelegate.h"! En FirstViewController.m! #import "FirstViewController.h"! - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {! if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {! // Custom initialization! self.title = @"¡Numero Uno!";! }! return self;! }! ...! - (void)applicationDidFinishLaunching:(UIApplication *)application {! // INICIALIZAR! navigationController = [[UINavigationController alloc] init];! [window addSubview:navigationController.view];! FirstViewController *viewController = ! [[FirstViewController alloc] ! initWithNibName:@"FirstView" bundle:nil];! [navigationController pushViewController:viewController ! animated:NO];! [viewController release];! // Override point for customization ! after application launch! [window makeKeyAndVisible];! }! Pila de vistas: UINavigationController! - (void)viewDidLoad {! [super viewDidLoad];! // AÑADIR BOTONES DE CONTROL! UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self ! action:@selector(add:)];! self.navigationItem.rightBarButtonItem = barButtonItem;! [barButtonItem release];! UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] ! initWithTitle:@"back" style:UIBarButtonItemStyleBordered target:nil ! action:nil];! self.navigationItem.backBarButtonItem = backBarButtonItem;! [backBarButtonItem release];! }! - (void)add:(id)sender! {! UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Nothing to add" message:@"Sorry, try again!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];! [alertView show];! [alertView release];! }! Pila de vistas: UINavigationController! en FirstViewController.m! - (IBAction)push:(id)sender! {! SecondViewController *secondViewController = [[SecondViewController alloc] initWithText:@"Something"];! [self.navigationController pushViewController:secondViewController animated:YES];! [secondViewController release];! }! en SecondViewController.m! - (id)initWithText:(NSString *)someText! {! if (self = [self initWithNibName:@"SecondView" ! bundle:nil]) {! // Custom initialization! self.title = @"Second";! self.text = someText;! }! return self;! }! DEMO: push-pop! Vector de vistas: UITabBarController! Vector de vistas: UITabBarController! - (void)applicationDidFinishLaunching:(UIApplication *)application { ! tabBarController = [[UITabBarController alloc] init];! • Controlador // Create a few view controllers! UIViewController *redViewController = [[UIViewController alloc] init];! redViewController.title = @"Red";! redViewController.tabBarItem.image = [UIImage imageNamed:@"faves.png"];! redViewController.view.backgroundColor = [UIColor redColor];! de la vista seleccionada! UIViewController *blueViewController = [[UIViewController alloc] init];! blueViewController.title = @"Blue";! blueViewController.tabBarItem.image = [UIImage imageNamed:@"search.png"];! blueViewController.view.backgroundColor = [UIColor blueColor];! • Iconos/nombres de todos los controladores de vistas! MyViewController *myViewController = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil];! // Add them as children of the tab bar controller! tabBarController.viewControllers = ! [NSArray arrayWithObjects:redViewController, ! blueViewController, myViewController, nil];! // Don't forget memory management! [redViewController release];! [blueViewController release];! [myViewController release];! // Add the tab bar controller's view to the window! [window addSubview:tabBarController.view];! [window makeKeyAndVisible];! }! Vector de vistas: UITabBarController! Vector de vistas: UITabBarController! Si añadimos muchos elementos al vector, añade automaticamente botón de “more ...” para:! • visualizar el resto y acceder! • configurar el orden! DEMO: MyTab! Vistas personalizadas! UITabBarController + UINavigationController! Muy común combinarlos! • Vista: área rectangular de la pantalla! • Dibuja y/o maneja eventos en esa zona! • Jerarquía • Una ...! SimpleFirstController *thirdNavView = [[SimpleFirstController alloc] init];! "thirdNavView.title=@"Alumnos";! superview: - (UIView *)superview ! • Varias "UINavigationController *navigationController3=[[UINavigationController alloc] init];! "[navigationController3 pushViewController:thirdNavView animated:NO]; "! "[thirdNavView release];! "NSArray *controllerArray =[[NSArray alloc] ! initWithObjects:navigationController1,navigationController2,navigationController3, nil]; "[tabController setViewControllers:controllerArray];! ...! de vistas: ! • (el " (o ninguna) subviews: - (NSArray *)subviews ! orden importa... transparencias!)! "! Vistas personalizadas! • Normalmente con I.Builder, pero a veces es necesario diseñar vista “manual”: dibujo personalizado y/o manejar eventos (siguiente clase).! • Superposición • Podemos entre vistas: se ve la que está más arriba! utilizar transparencias para ver las sub-vistas de abajo:! • Al dibujar (siguiente...), transparencia por defecto es: opaco 100%. ! • Para ocultar una vista del todo: hidden property= YES! DIBUJAR en pantalla! • Accedemos a los “pixels” de la pantalla que queremos pintar! • Coordenadas • CGFloat en pantalla: ! (un float “normal”, usar siempre este tipo para graficos)! • CGPoint (struct de C con dos CGFloats: x,y. Se crea con CGPointMake(x, y) )! • CGSize (struct de C con dos CGFloats: width and height. Se crea con CGSizeMake(width, height)! • CGRect (struct de C con un CGPoint origin y un CGSize size. Se crea con CGRectMake(x, y, width, height)! DIBUJAR en pantalla! (local): alto y largo de la vista. Se usa cuando se está implementando una vista! DIBUJAR EN PANTALLA! • Bounds • Subclase y center (global): rectángulo que contiene a la vista. Centro relativo a la super-view. Se usa para posicionar la vista dentro de su “superview”.! • Frame • Origen: • Frame arriba a la izquierda!!! >= bounds (rotaciones)! • - (void)drawRect:(CGRect)clipRect;! • se puede optimizar, no es necesario, no dibujando lo que hay fuera de clipRect! • NUNCA!! llamar directamente a drawRect: avisar que la vista no está actualizada y necesita “redibujar”: drawRect será llamado en el momento adecuado.! View B bounds: ((0,0),(200,250)) ! • - (void)setNeedsDisplay ó - (void)setNeedsDisplayInRect:(CGRect)clipRect! View B frame: ((140,65),(320,320)) ! View B center: (300, 225)! DIBUJAR EN PANTALLA! • Contexto • del dibujo: ! DIBUJAR EN PANTALLA! • Path a dibujar: ! Determina dónde va el dibujo (pantalla, pdf,...)! • Empezar el path: CGContextBeginPath(context);! • Sólo dura una ejecución de drawRect (nunca almacenar)! • Mover el “lápiz”, haciendo rectas y arcos: ! • Se obtiene el contexto actual: ! • • de UIView: implementar el método drawRect.! - (CGContextRef)UIGraphicsGetCurrentContext();! CGContextRef context = UIGraphicsGetCurrentContext();! • CGContextMoveToPoint(context, 75, 10); CGContextAddLineToPoint(context, 10, 150); ...! • Cerrar el path: CGContextClosePath(context);! • Establecer propiedades y dibujar el path: ! [[UIColor greenColor] setFill]; ! [[UIColor redColor] setStroke]; CGContextDrawPath(context, kCGPathFillStroke);! • Estilo del dibujo. Se pueden configurar múltiples opciones (fuente, color, tamaño,...): CGContextSetLineWidth(context, 1.0); ! • Se puede almacenar un path para reutilizarlo, usando CGPath en lugar de CGContext! DIBUJAR EN PANTALLA! Model-View-Controler! • RECORDAR: Flujo de información a través de los controladores! DEMO: happy! Vistas con tablas y “scroll”! • Vistas más flexibles: UIScrollView! • Para mostrar más cosas de las que caben en la pantalla! • Soporta eventos de zoom y de “scroll”! • Subclases: Vistas con tablas y “scroll”! • UITableView: mostrar listas de contenido (1columna, varias filas) permitiendo “scroll” vertical! UITableViewStylePlain! Cabecera tabla! UITableViewStyleGrouped! Cabecera tabla! Cabecera sección! Cabecera sección! Celda! UITableView and UITextView! Celda! Pie sección! Pie sección! Sección! Sección! Pie tabla! Pie tabla! Vistas con tablas y “scroll”! Solución simple! Solución más eficiente! Otro objeto (datasource: Utilizar un vector para pasar los UITableViewController) pasa los datos a la tabla (como un datos a mostrar! [myTableView setList:myListOfStuff];! “delegate”). Los datos se cargan Pero!! Se cargan todos los datos conforme hacen falta!! al principio y se quedan en Cuantas secciones visibles?! Qué mostrar en celda de sección 1?! memoria! 5! John Appleseed! Vistas con tablas y “scroll”! Muchas opciones de configuración en UITableView! • Apariencia de filas y celdas: estilos de celda(UITableViewCellStyleDefault,...), otros “accesorios” (UITableViewCellAccessoryType)! • Responder a eventos de selección: didSelectRowAtIndexPath:(NSIndexPath *)indexPath; willSelectRowAtIndexPath (NSIndexPath *)indexPath! UITableViewControllerCrea automáticamente un Table view, es su “delegate” y “datasource”.! • El • Se ocupa de acciones por defecto: reloadData al princripio, deselecciona filas al navegar hacia atrás, ...! Vistas con tablas y “scroll”! Muchas opciones de configuración en UITableView! • Re-utilizar celdas! UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“MyIdentifier”]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:... reuseIdentifier:@“MyIdenifier”] autorelease]; } ! • Cargar datos bajo demanda: cuando una fila se hace visible (automático) o cuando se llama explicitamente “reloadData”! - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.tableView reloadData]; }