desarrollo de aplicaciones para dispositivos móviles...
TRANSCRIPT
Desarrollo de aplicaciones para dispositivos móviles:
Programación para iOS
Luis Montesano ' Bob D/ Nvsjmmp
• Ana Cris Murillo
Contacto: [email protected]
Profesora del Dpto. de Informática e Ing. de Sistemas, Universidad de Zaragoza.
Investigación en visión por computador y robótica
• Luis Montesano
Contacto: [email protected]
Profesor del Dpto. de Informática e Ing. de Sistemas, Universidad de Zaragoza.
Investigación en aprendizaje y robótica
Profesorado
• Información accesible en pdf y en web (Objective C, XCode, Cocoa, … ) Actualizaciones y complementos al material durante el curso
• iPhone Dev center (http://developer.apple.com/iphone/index.action)
• Curso programación iPhone Stanford (iTunes)
Materiales, documentación, código ...
Índice de este fin de semana • Repaso opciones diseño vistas básico
- “hello world”? usando Xcode e IB.
- ModelViewController. Vista simple.
• Navegación:
- Navigation controller, Tab Bar, Híbrido.
- Construcción de ejemplo base para “proyecto de asignatura”.
• Vistas avanzadas:
- Tablas, Vistas Personalizadas
“Hello World”: ���Objective C, Xcode, IB.
MVC en una vista “simple”
MVC en una vista “simple”
• Patrón Model-View-Controller
• Una clase
• Un viewController sencillo
Diseño de aplicaciones: opciones de navegación
Control de navegación: “navigation controlers”
Barra de navegación: UINavigationController
Barra de “tabs”: UITabBarController
Híbrido ...
Vector de vistas: UITabBarController
• Controlador de la vista seleccionada
• Iconos/nombres de todos los controladores de vistas
- (void)applicationDidFinishLaunching:(UIApplication *)application { !
tabBarController = [[UITabBarController alloc] init]; !
// 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]; !
UIViewController *blueViewController = [[UIViewController alloc] init]; ! blueViewController.title = @"Blue"; ! blueViewController.tabBarItem.image = [UIImage imageNamed:@"search.png"]; ! blueViewController.view.backgroundColor = [UIColor blueColor]; !
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
Vector de vistas: UITabBarController
DEMO: MyTab
Añadimos “vector” de “tabs” a la agenda-base (con uno de los tabs la vista “sencilla”)
Pila de vistas: UINavigationController
• Título del controlador de la vista encima de la pila.
• Título del controlador de la vista anterior
• Vista encima de la pila
• Barra de herramientas de la vista encima de la pila
Pila de vistas: UINavigationController • Personalizar 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 el título por algún “control”: self.navigationItem.titleView = segmentedControl;
• Botón 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;
en "MyAppDelegate.h" !
#import "FirstViewController.h"!
... !
- (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
En FirstViewController.m !
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { ! if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { ! // Custom initialization! self.title = @"¡Numero Uno!"; ! } ! return self; !} !
- (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; !} !
Pila de vistas: UINavigationController
Pila de vistas: UINavigationController
DEMO: push-pop
UITabBarController + UINavigationController Muy común combinarlos
... !
SimpleFirstController *thirdNavView = [[SimpleFirstController alloc] init]; !"thirdNavView.title=@"Alumnos"; !
"UINavigationController *navigationController3=[[UINavigationController alloc] init]; !"[navigationController3 pushViewController:thirdNavView animated:NO]; "!"[thirdNavView release]; !
"NSArray *controllerArray =[[NSArray alloc] !initWithObjects:navigationController1,navigationController2,navigationController3, nil]; " "!"[tabController setViewControllers:controllerArray]; !
... !
Añadimos a los “tabs”de la agenda-base al menos un controlador del tipo “navigation controller”
Recopilando …
“navigation controlers”
Barra de navegación: UINavigationController
Barra de “tabs”: UITabBarController
Híbrido ...
Esquema general • Crear proyecto nuevo
- Window-based: solo ventana “base”, ninguna “subview” añadida.
- View-based, Navigation-based y Tab-based incluyen automáticamente una subview a la ventana principal inicializada de la manera correspondiente en cada caso
- (void)applicationDidFinishLaunching:(UIApplication *)application {! ... !
ó [window addSubview:[(my)viewController view]]; !//inicializa por defecto el viewController con appNameViewController (UIView) en MainWindow.xib!
ó [window addSubview:[(my)navigationController view]]; !//inicializa por defecto con RootViewController (que es una tableView) en MainWindow.xib!
ó [window addSubview:[(my)tabBarController view]]; //LO MISMO QUE![window addSubview:(my)tabBarController.view]; !
[window makeKeyAndVisible]; !
Esquema general • Crear proyecto nuevo
- Window-based: solo ventana “base”, ninguna “subview” añadida.
- View-based, Navigation-based y Tab-based incluyen automáticamente una subview a la ventana principal inicializada de la manera correspondiente en cada caso
• Y personalizar (my) viewControllers antes de hacer el “addsubview” (código o IB)
//inicializar viewController!
//inicializar viewController inicial y hacer “push” en la pila del navigationControler
//inicializar viewControllers necesarios y “rellenar” vector del tabBarControler
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: UITableView and UITextView
Vistas con imágenes
Mostrar una imagen “grande” en un “scroll view”
UIImage *image = [UIImage imageNamed:@"smartphones.jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:screenBounds];
[scrollView addSubview:imageView];
scrollView.contentSize = image.size;
[self.view addSubview:scrollView]; !
Vistas con tablas Class: UITableView, UITableViewCell, UITableViewController Protocols: UITableViewDelegate, UITableViewDataSource
UITableViewStylePlain UITableViewStyleGrouped
Cabecera tabla Cabecera tabla
Pie tabla
Pie tabla
Cabecera sección Cabecera sección
Pie sección Pie sección
Sección Sección
Celda Celda
:UIScrollView, 1columna, varias filas/secciones
Vistas con tablas
Usually: UITableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
DataSource: Qué se ve (datos) y sus propiedades
• NSArray • Cuántas secciones y filas? • Data for a given [section, row] • Contenido de headers y footers. • Propiedades de “edición” de elementos de la tabla: insert, rearrange, delete
Delegate: Cómo se ve y qué ocurre con la vista (eventos)?
• Tamaño de celdas, filas, cabeceras • Estilo de celdas • “Eventos” de celda_va_a_aparecer • “Eventos” de fila_seleccionada y permisos de ser seleccionado o no • Auto-select/deselect filas si hace falta • Recarga datos antes de hacerse visible. • Otros: edit button, flashes scroll, deja sitio para el teclado si hace falta
Class: UITableView, UITableViewCell, UITableViewController Protocols: UITableViewDelegate, UITableViewDataSource
Solución simple Solución más eficiente
Utilizar un vector para pasar los datos a mostrar [myTableView setList:myListOfStuff]; Pero!! Se cargan todos los datos al principio y se quedan en memoria
Otro objeto (datasource: UITableViewController) pasa los datos a la tabla (como un “delegate”). Los datos se cargan conforme hacen falta!
Cuantas secciones visibles? Qué mostrar en celda de sección 1?
5 John Appleseed
Vistas con tablas
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
• El UITableViewController crea automáticamente un Table view, es su “delegate” y “datasource”.
• Se ocupa de acciones por defecto: reloadData al principio, de-selecciona filas al navegar hacia atrás, …
Vistas con tablas
Muchas opciones de configuración en UITableView
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];}
• Re-utilizar celdas
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“MyIdentifier”];if (cell == nil) { cell = [[[UITableViewCell alloc]initWithStyle:... reuseIdentifier:@“MyIdenifier”] autorelease]; }
• Personalizar celdas (tanto apariencia como atributos de “datos”)
Vistas con tablas
Vistas con tablas
DEMO: recipes Añadimos vista de tabla a la “agenda” base (más avanzado: ejemplo “The Elements”)