Curs Cocoa ::: AppDot ::: Part 2
En aquesta segona part de l'aplicació AppDot mirarem d'afegir més funcionalitat a l'aplicació per a que es pugui canviar el radi i el color del punt. Mirarem com funcionen el paradigma Target/Action a l'hora de realitzar accions sobre controls de la interfície gràfica.

Podeu trobar aquesta nova classe en la plana destinada als vídeos del curs. Allà hi podeu trobar els vídeos, el projecte que s'ha desenvolupat i l'enllaç a aquest tema del fòrum.
- http://public.poble.cat/MacOSX/XCode/#cocoa-appdot-cap2
07 juny 2008 09:57
Hola Xin, e començat a fer l'adaptació de la segona part del AppDot per l'iPhone i m'he trobat un problema que amb el que no trobo solució, a veure si em pots ajudar. El problema es amb NSSlider. Bé, per començar no pots utilitzar aquest objecte, només existeix UISlider, que en la part del Interface Builder es igual, però al codi es diferent. Es veu que com a argument s'envia a si mateixa com a propietat i no com a objecte, així donçs el mètode:
- (IBAction)changeRadius:(id)sender {
radius = [sender floatValue];
}No funciona, l'aplicació es penja. Primer vaig canviar IBAction per void però no té res a veure.
Aleshores vaig intentar:
- (void)changeRadius:(id)sender {
radius = [sender valueForKey:@"value"];
}Però em diu "incompatible types in assignment". El radius es del tipus CGFloat, no sé si tindria que fer algun tipus de casting, però no estic segur.
Pel que he llegit a Internet, podria ser un bug, se't acut alguna possible solució?
14 juny 2008 11:31
Ara estic actualitzant la documentació de l'iPhone. Cal mirar l'objecte UISlider, viam quines propietats té. M'estranya que no sigui un objecte, si no ho és no pots utilitzar el sender. En el meu codi, el sender és el control que executa l'acció, en aquest cas el NSSlider.
Viam si s'acaba d'actualitzar la documentació... 
14 juny 2008 12:30
En la documentació diu que només cal accedir al value, però això no es cert.
Per cert, cada actualització de la documentació es un cop d'estat a la connexió!
14 juny 2008 12:52
Doncs, sí. I al processador, un cop s'ha descarregat. Porto 30 minuts amb el portàtil col·lapsat. No podia ni carregar les pàgines d'Internet. 
14 juny 2008 13:43
Jaime, prova-ho així:
- (IBAction)changeRadius:(id)sender {
radius = [[sender valueForKey:@"value"] floatValue];
}He llegit per internet que la documentació no és del tot correcta. A banda que hi ha problemes per accedir al valor directament amb la funció.
Només es pot accedir al valor amb "valueForKey" i aquest no retorna un Float, sinó un NSNumber amb un float a dins. Per tant per accedir al valor float, has d'utilitzar el mètode "floatValue" del valor retornat. 
14 juny 2008 14:21
Per cert, el fet de canviar "IBAction" per "void" no afecta en res. IBAction és un sinònim de void.
14 juny 2008 14:24
Si! Ara si funciona! Molt bé, ja puc continuar amb l'exemple. Per cert, es poden baixar aquest screencast per l'itunes? Es que només m'apareix la serie de "Curs de programació XCode".
Sobre l'IBAction, es cert, el canviava perquè no apareix a la documentació del iPhone, però està clar que està incompleta i com que si que em funciona l'exemple, ja no ho faré més.
Gracies!
14 juny 2008 19:49
Sí que hi és el podcast. Però us vull fer passar pel web, per aconseguir fer-me ric amb els anuncis de google. Ja en porto 2 EUR, per fi podré menjar calent. 
Fora bromes, aquí tens l'enllaç: 
- itpc://blip.tv/bookmarks/rss/162235/itunes
14 juny 2008 21:36
Per passar aquesta aplicació a l'iphone hi han agut dues diferencies principals. La primer es que s'utilitza UISlider en comptes del NSSlider, que gracies en Xin s'ha solucionat. La segona ha sigut a l'hora d'escollir color, ja que el ColorWell no existeix per l'iPhone, cosa lògica ja que no seria gaire còmode, al menys en la seva versió actual. Es per això que he fet una versió reduïda que podeu veure al final del post en una imatge (espero) :
El DotView.h :
#import <UIKit/UIKit.h>
// En CocoaTouch es UIView en vez de NSView
@interface DotView : UIView {
CGPoint center;
CGFloat radius;
// per escollir el color del cuadrat
UIColor *dotColor;
}
- (IBAction)changeRadius:(id)sender;
@end
El DotView.m:
#import "DotView.h"
@implementation DotView
// ja que el view es muntarà per codi, hem d'utilitzar initWithCoder en comptes de initWithFrame
- (id)initWithCoder:(NSCoder *)coder {
if (self = [super initWithCoder:coder]) {
center = CGPointMake(160.0,240.0);
radius = 50.0;
// definim un color inicial
dotColor= [UIColor redColor];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Canviar el color de la vista, blau perquè el fons de l'aplicació per defecte és blanc
CGRect bounds = [self bounds];
[[UIColor blueColor] set];
UIRectFill(bounds);
// crear plafó de selecció de colors
// Vermell
[[UIColor redColor]set];
UIRectFill(CGRectMake(0, 0, 80, 80));
// Verd
[[UIColor greenColor]set];
UIRectFill(CGRectMake(80, 0, 80, 80));
// Blanc
[[UIColor whiteColor]set];
UIRectFill(CGRectMake(160, 0, 80, 80));
// Negre
[[UIColor blackColor]set];
UIRectFill(CGRectMake(240, 0, 80, 80));
// Crear el cuadrat
CGRect dotRect= CGRectMake(center.x - radius, center.y - radius, 2*radius, 2*radius);
[dotColor set];
UIRectFill(dotRect);
}
// TOUCH
// Detectar un punt en la pantalla
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchCoordinates = [touch locationInView:self];
// si el punt es dins el plafó de selecció de color, escollir el color correcte
if(touchCoordinates.y<=80)
{
if(touchCoordinates.x<=80){ dotColor = [UIColor redColor]; }
else if(touchCoordinates.x<=160){ dotColor = [UIColor greenColor]; }
else if(touchCoordinates.x<=240){ dotColor = [UIColor whiteColor]; }
else{ dotColor = [UIColor blackColor]; };
}
else
// moure el cuadrat
{
center = touchCoordinates;
};
[self setNeedsDisplay];
}
// Redibuixaar el cuadrat al arrossegar
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesBegan:touches withEvent:event];
}
// Canviar el radius
- (IBAction)changeRadius:(id)sender {
radius = [[sender valueForKey:@"value"] floatValue];
[self setNeedsDisplay];
}
- (IBAction)dealloc {
[super dealloc];
}
@end
I aquí el resultat:

14 juny 2008 21:52
<a href="http://stay-still.com/viewer.php?file=wwa5lv5jc4h16472glw8.jpg"><img src="http://stay-still.com/images/wwa5lv5jc4h16472glw8_thumb.jpg" border="0" alt="wwa5lv5jc4h16472glw8.jpg" /></a>
14 juny 2008 21:52
hm... no sé com penjar la foto 
14 juny 2008 21:53
Per penjar imatges millor utilitzar ImagesHack:
- http://imageshack.us/
Hi ha moltes webs que no deixen mostrar les seves imatges. 

14 juny 2008 22:00
Per cert, aquesta solució dels colors és una mica matussera. Hagués estat millor utilitzar 4 botons.
14 juny 2008 22:09
Si, la veritat es que la solució que he aportat se'n va una mica..., es que estic fent proves amb subviews i el que anava a dir es que el problema de utilitzar la solució que proposo es que els quadrats de selecció de color es re-dibuixen cada cop, que lo millor seria fer un subview amb el quadrat que es mou i que fos només aquest subivew el que s'actualitzi... però ara que hi penso, seria un tema per un altre dia...
Però ja que la meva proposta a sigut aquesta, voldria fer una correcció y es que com e utilitzat una referència de una classe, es tindria que buidar de la memòria al dealloc... encara que en realitat al iPhone al sortir d'una aplicació, es tanca completament, em sembla mes correcte fer-ho així:
- (IBAction)dealloc {
[dotColor release];
[super dealloc];
}ah! i gracies per l'enllaç!
14 juny 2008 22:58
Viam si trobo un moment i faig algunes proves amb l'iPhone. Tinc ganes de fer alguna petita aplicació. Però primer he de canviar la idea que tinc de programació sobre ordinadors amb ratolí i amb pantalles grans. Cal adaptar-se a la filosofia de l'iPhone. 
15 juny 2008 10:51
ejem... també:
// si el punt es dins el plafó de selecció de color, escollir el color correcte
if(touchCoordinates.y<=80)
{
[dotColor release];
if(touchCoordinates.x<=80){ dotColor = [UIColor redColor]; }
.
.
.
}
Dons jo porto un temps desenvolupant per a mòbils, i la veritat es que la mentalitat es forçadament diferent. A part dels milers de sistemes operatius, hi ha una raó principal i es la mida de la pantalla, que t'obliga a presentar la informació de forma molt diferent, però també has de pensar en quines situacions es podria trobar l'usuari: es al carrer? està de peu? te poca estona? te connexió a la xarxa?
Però penso que l'iPhone ajuda en temes molt importants coma a una estandardització de resolució i proporció de pantalla, processador, forma de interactuar. En els mòbils tot això es diferent, normalment insuficient i el pitjor son els teclats, tant i tant diferents!
Bé, quan facis alguna prova ja ens diràs les teves experiències!
15 juny 2008 11:45
