- Abrir Xcode y crear un nuevo proyecto con el nombre de FavoriteTwitterSearchs, le damos click a MainWindow.xib para abrir interface builder
- Agarramos un Label desde la Libreria y lo nombramos Favorite Twitter Searches, en el inspector incrementamos el Font Size a 18, Centramos el Label en la parte superior de la ventana usando Layout> Alignment>Align Horizontal Center in Container.
- Después arrastramos dos Text Fields hacia la ventana de la aplicación.
- Seleccionamos el primer Text Field. En el Tab de Atributos del Inspector, agregamos este siguiente texto " Enter query expression here" en el PlaceHolder Field.
- En el segundo Text Field hacemos lo mismo con la diferencia de que escribiremos "Tag your search".
- Agarramos un Round Rect Button de la libreria en la ventana de la aplicación. En el tab de Atributos del Inspector, colocamos como titulo ( Title) Save.
- Ahora agarramos un View desde la libreria, lo expandamos hasta que cubra la aplicacion debajo de los Text Fields.
- Seleccionamos este View y abrimos Inspector, vamos al atributes tab y le damos click al background y esto abrira la ventana Colors.
- Damos click en el segundo tab, y seleccionamos RGB Slider de la lista. Cualquier color puede ser creado de la combinacion del rojo, verde y azul, a estos componentes se los conoce como RGB values. Escogemos un color y cerramos la ventana Color y volvemos a la ventana de la aplicacion. El colo de el View cambia el reflejo del nuevo color.
- Ahora agarramos un nuevo Label adentro del View y le escribimos como texto Tagged Searches. En el Inspector, Cambiamos el color a blanco si escogimos un color oscuro y centramos el texto
- Agarramos un nuevo Round Rect Button de la libreria hacia la parte inferior de la ventana de la aplicacion, le damos doble click y la nombramos " Clear all Tags ".
- Despues Agregamos a nuestra ventana de la aplicacion ( Una instancia de la clase UIScrollView), lo cual permite al usuario ir atraves el contenido si es muy grande para mostrarlo en la pantalla. La ubicacion del Scroll View sera entre el Label "Tagged Searches" y el boton " Clear all Tags"
- Abrimos Xcode, seleccionamos la Classes y creamos una nueva clases como lo discutimos en el capitulo anterior. Asegurense de que NSObject este seleccionado en la Subclass de la lista. Le damos click a Finish .
- Abrimos el archivo Controller.h y ponemos el Codigo numero uno que esta adjuntado al final del Capitulo.
- Una vez que terminamos de editar Controller.h, guardamos y abrimos el archivo MainWindow.xib en Interface Builder.
- Despues de esto agarramos un Object de Library y los ubicamos en la ventana MainWindow.xib.
- Seleccionamos el Objeto y vamos al inspector en el Tab Identity y cambiamos el valor en la clase a Controller.
- Cambiamos a el Tab Connections en el inspector. aqui encontraremos 3 outlets que conectaremos con sus correspondientes GUI components.
- Despues vamos a conectar los eventos generados por los componentes GUI con sus correspondientes acciones. Los eventos generados en esta aplicacion son enviados por los Objetos ( Button ). Para esto seleccionamosel "Save" Button y abrimos el Tab Connection en el Inspector. En este caso usaremos el evento (Event) Touch Up Inside, desde el circulo lo arrastramos hacia el Objeto Controller en la Ventana Window y escogemos addTag: de la lista.
- ahora seleccionamos el boton Clear All Tags, vamos a Inspector y escogemos el evento Touch Up Side, Arrastramos hacia el objeto Controller y seleccionamos clearTags: de la lista,
- Grabamos y Cerramos Interface Builder
- Ahora vamos a usar la segunda parte del Codigo en el archivo Controller.m
- Grabamos y ejecutamos (Build and Run)
// Controller.h
// Controller class for the Favorite Twitter Searches app.
#import
// constants that control the height of the buttons and the spacing
#define BUTTON_SPACING 10
#define BUTTON_HEIGHT 40
@interface Controller : NSObject // this line is autogenerated
{
// Interface Builder outlets
IBOutlet UIScrollView *scrollView; // for scrollable favorites
IBOutlet UITextField *tagField; // text field for entering tag
IBOutlet UITextField *queryField; // text field for entering query
// stores the tag names and searches
NSMutableDictionary *tags;
// stores the Buttons representing the searches
NSMutableArray *buttons;
// stores the info buttons for editing existing searches
NSMutableArray *infoButtons;
// location of the file in which favorites are stored
NSString *filePath;
} // end instance variable declarations
- (IBAction)addTag:sender; // adds a new tag
- (IBAction)clearTags:sender; // clears all of the tags
- (void)addNewButtonWithTitle:(NSString *)title; // creates a new button
- (void)refreshList; // refreshes the list of buttons
- (void)buttonTouched:sender; // handles favorite button event
- (void)infoButtonTouched:sender; // handles info button event
@end // end Controller interface
// begin UIButton's sorting category
@interface UIButton (sorting)
// compares this UIButton's title to the given UIButton's title
- (NSComparisonResult)compareButtonTitles:(UIButton *)button;
@end // end catagory sorting of interface UIButton
Controller.m
// Controller.m
// Controller class for the Favorite Twitter Searches app.
#import "Controller.h" //this line is auto-generated
@implementation Controller //this line is auto-generated
// called when object is initialized
- (id)init
{
self = [super init]; // initialize the superclass members
if (self != nil) // if the superclass initialized properly
{
// creates list of valid directories for saving a file
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
// get the first directory
NSString *dir = [paths objectAtIndex:0];
// concatenate the file name "tagsIndex.plist" to the path
filePath = [[NSString alloc] initWithString:
[dir stringByAppendingPathComponent:@"tagsIndex.plist"]];
NSFileManager *fileManager = [NSFileManager defaultManager];
// if the file does not exist, create an empty NSMutableDictionary;
// otherwise, initialize an NSDictionary with the file's contents
if ([fileManager fileExistsAtPath:filePath] == NO)
{
tags = [[NSMutableDictionary alloc] init];
} // end if
else
{
tags = [[NSMutableDictionary alloc]
initWithContentsOfFile:filePath];
} // end else
buttons = [[NSMutableArray alloc] init]; // create array
infoButtons = [[NSMutableArray alloc] init]; // create array
} // end if
return self; // if self == nil, object not initialized properly
} // end method init
// called when the GUI components finish loading
- (void)awakeFromNib
{
for (NSString *title in tags)
[self addNewButtonWithTitle:title];
} // end method awakeFromNib
// remove all buttons and populate View with favorites
- (void)refreshList
{
// remove all the buttons from the GUI
for (UIButton *button in scrollView.subviews)
[button removeFromSuperview];
[infoButtons removeAllObjects];
float buttonOffset = BUTTON_SPACING; // reset the spacing
// repopulate the scroll view with buttons
for (UIButton *button in buttons)
{
CGRect buttonFrame = button.frame; // fetch the frame of button
buttonFrame.origin.x = BUTTON_SPACING; // set the x-coordinate
buttonFrame.origin.y = buttonOffset; // set the y-coordinate
// button width is the size of the view minus padding on each side
buttonFrame.size.width =
scrollView.frame.size.width - 5 * BUTTON_SPACING;
buttonFrame.size.height = BUTTON_HEIGHT; // set the height of button
button.frame = buttonFrame; // assign the new frame to button
[scrollView addSubview:button]; // add button as a subview
// create detail button
UIButton *infoButton =
[UIButton buttonWithType: UIButtonTypeDetailDisclosure];
[infoButtons addObject:infoButton]; // add infoButton to infoButtons
// position button to the right of the button we just added
buttonFrame = infoButton.frame; // fetch the frame of infoButton
buttonFrame.origin.x = scrollView.frame.size.width - 35;
// this button is a bit shorter than normal buttons, so we adjust
buttonFrame.origin.y = buttonOffset+3;
infoButton.frame = buttonFrame; // assign the new frame
// make the button call infoButtonTouched: when it is touched
[infoButton addTarget:self action:@selector(infoButtonTouched:)
forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:infoButton]; // add infoButton as a subview
// increase the offset so the next button is added further down
buttonOffset += BUTTON_HEIGHT + BUTTON_SPACING;
} // end for
} // end refreshList
// called when the user touches an info button
- (void)infoButtonTouched:sender
{
// get the index of the button that was touched
int index = [infoButtons indexOfObject:sender];
// get the title of the button
NSString *key = [[buttons objectAtIndex:index] titleLabel].text;
tagField.text = key; // update tagField with the button title
// get the search query using the button title
NSString *value = [tags valueForKey:key];
queryField.text = value; // update queryField with the value
} // end method infoButtonTouched:
// add a favorite search
- (IBAction)addTag:sender
{
// make the keyboard disappear
[tagField resignFirstResponder];
[queryField resignFirstResponder];
NSString *key = tagField.text; // get the text in tagField
NSString *value = queryField.text; // get the text in queryField
// test if either field is empty
if (value.length == nil || key.length == nil)
return; // exit from the method
if ([tags valueForKey:key] == nil) // test if the tag already exists
[self addNewButtonWithTitle:key]; // if not, add a new button
[tags setValue:value forKey:key]; // add a new entry in tags
tagField.text = nil; // clear tagField of text
queryField.text = nil; // clear queryField of text
[tags writeToFile:filePath atomically:NO]; //save the data
} // end method addTag:
// remove all the tags
- (IBAction)clearTags:sender
{
[tags removeAllObjects]; // clear tags
[tags writeToFile:filePath atomically:NO]; // update favorite file
[buttons removeAllObjects]; // clear buttons
[self refreshList]; // update the display
} // end clearTags:
// add a new button with the given title to the bottom of the list
- (void)addNewButtonWithTitle:(NSString *)title
{
// create a new button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
// give the button the title of the tag
[button setTitle:title forState:UIControlStateNormal];
// tell the button to call buttonTouched: when it is touched
[button addTarget:self action:@selector(buttonTouched:)
forControlEvents:UIControlEventTouchUpInside];
[buttons addObject:button]; // add the UIButton to the end of the array
// sort the NSMutableArray by the UIButton's titles
[buttons sortUsingSelector:@selector(compareButtonTitles:)];
[self refreshList]; // refresh the list of favorite search Buttons
// Adjust the content size of the view to include the new button. The
// view scrolls only when the content size is greater than its frame.
CGSize contentSize = CGSizeMake(scrollView.frame.size.width,
buttons.count * (BUTTON_HEIGHT + BUTTON_SPACING) + BUTTON_SPACING);
[scrollView setContentSize:contentSize];
} // end addNewButtonWithTitle:
// load selected search in web browser
- (void)buttonTouched:sender
{
NSString *key = [sender titleLabel].text; // get Button's text
// get the search and replace special characters with percent escapes
NSString *search = [[tags valueForKey:key]
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// format the URL
NSString *urlString = [NSString stringWithFormat:
@"http://search.twitter.com/search?q=%@", search];
NSURL *url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
} // end buttonTouched
@end // end implementation Controller
// define UIButton's sorting category method
@implementation UIButton (sorting)
- (NSComparisonResult)compareButtonTitles:(UIButton *)button
{
// compare this UIButton's title to that of the given UIButton
return [self.titleLabel.text
caseInsensitiveCompare:button.titleLabel.text];
} // end method compareButtonTitles
@end // end UIButtons's sorting category
12 comments:
Tu curso me a servido mucho ... Recientemente compre una iMac para poder hacer apps... pero aquí en México es difícil encontrar tutoriales o algún tipo de curso ... lo único que me gustaría un poco mas de tu curso es que subas capítulos mas seguido... pero aun así muchas gracias !!!
Genial sin duda de lo mejor que he visto.
Muchas gracias por tus aportes. Para cuando los próximos?
Un saludo!
Muy interesante tu artículo y muy bien explicado y detallado. No puedo acceder a los anteriores (2 y 1), ¿puedes decirme como please?
Al final de estaa pagina hay un link q dice Entradas antiguas. Alli estan los capitulos anteriores
Muy bien me estan gustando, ya que hay pocos sitios que te expliquen como programar para iphone en españo!! sigue asii!! cada cuanto tiempo tienes pensado en ir subiendo los capitulos??
Interesante no se si es porque tengo la ultima SDK, pero el text del controller.m me arroja 32 errores y 5 failed
me tira un solo warning.. quizas puedan ayudarme soy nuevo en esto, dice..
warning: no rule to process file '$(PROJECT_DIR)/Classes/controller.h' of type sourcecode.c.h for architecture i386
Si alguien me da una mano les voy a estar agradecido.. graciaaas de todas maneras.
estos tutoriales sirven para el SDK 4.0.1? o como le hago para bajar uno anterior y practicar? y ta,bien pues tu pusiste los textos de los codigos, y eso como puedo aprender a hacerlo?
Los ejemplos estan muy bien, pero ...
Seleccionamos el Objeto y vamos al inspector en el Tab Identity y cambiamos el valor en la clase a Controller.
Cambiamos a el Tab Connections en el inspector. aqui encontraremos 3 outlets que conectaremos con sus correspondientes GUI components.
No me aparece nada, que hago mal?
Trabajo con Xcode 3.2.5
Saludos
EnJofre@: Primeramente gracias por seguir mi Blog.
Segundo: segun estas haciendo los pasos deben aparecer los outlets.
solamente asegurate de que en la ventana mainWindow.xib hayas seleccionado Controller.
Si deseas enviarme una impresion de tu pantalla para ver donde esta el problema.
Saludos
Hola, para cuando las siguientes entradas?, o ya no vas a actualizar mas este blog? saludos
Hola, estoy buscando información para hacer una aplicación universal, es decir que la aplicación ejecute unas instrucciones en el ipad y otras distintas en el iphone y la verdad es que no encuentro nada, a ver si alguien me puede ayudar. Os dejo mi correo: PascualArroyo@me.com
Publicar un comentario