'Mobile' Categoría


iPad: pantallas de manejar de arranque

IPhone de Apple y el iPod se utiliza para administrar un solo archivo de imagen para cargar la aplicación, el archivo Default.png . IPad de Apple, sin embargo, la orientación de la gestión de diferentes requiere el uso de múltiples archivos de imagen, para asegurarse de que vea la pantalla de forma correcta basada en la orientación del dispositivo. Durante el inicio de aplicaciones, como fue el caso para el iPhone, no es posible intervenir en el código de "maravilla" como el dispositivo orientado. Afortunadamente, se introdujo en la carga automática de los archivos especiales dependiendo de la orientación:

Los archivos son compatibles actualmente, además de los clásicos Default.png no recomendamos el uso, ya que se escala y se deforma de acuerdo a la orientación, son los siguientes:

  • Default-Portrait.png
  • Default-PortraitUpsideDown.png
  • Default-Landscape.png
  • Default-LandscapeLeft.png
  • Default-LandscapeRight.png

e LandscapeRight possono essere utilizzate per determinare orietamento e verso di quest'ultimo. Versiones PortraitUpsideDown , LandscapeLeft y LandscapeRight se puede utilizar para determinar orietamento y hacia la segunda.

Aplicación para empezar, entonces, según lo recomendado por Apple, es bueno "rediseño" - cuando sea necesario - a nuestros puntos de vista que actúan dentro de application:didFinishLaunchingWithOptions .

Continuación ...

setAnimationDidStopSelector: diferentes usos y avanzados

En la mayoría de los casos, o porque estamos acostumbrados o porque hemos visto en los tutoriales y en algunos textos, se utiliza el setAnimationDidStopSelector de esta manera:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
nil context : NULL ] ; [BeginAnimations UIView: contexto nada: NULL];
1.5 ] ; [UIView setAnimationDuration: 1,5];
UIViewAnimationCurveEaseInOut ] ; [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
self ] ; [SetAnimationDelegate UIView: auto];
@selector ( removeView ) ] ; [UIView setAnimationDidStopSelector: @ selector (removeView)];

; myView.alpha = 0;

; [CommitAnimations UIView];

/ /

void ) removeView { - (Void) {removeView
; [MyView removeFromSuperview];
}

come delegato e tramite la setAnimationDidStopSelector gli invia un messaggio removeView quando l'animazione è terminata. En el código anterior el setAnimationDelegate conjunto self como delegado ya través de setAnimationDidStopSelector envía un mensaje removeView cuando la animación ha terminado. El código es correcto, sin embargo, hace uso de una definición de mensaje ( removeView ) que podrían ser omitidos. Ahora, aquí es el mismo código, con el mismo efecto, sin el mensaje de removeView :

1
2
3
4
5
6
7
8
9
nil context : NULL ] ; [BeginAnimations UIView: contexto nada: NULL];
1.5 ] ; [UIView setAnimationDuration: 1,5];
UIViewAnimationCurveEaseInOut ] ; [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
myView ] ; [SetAnimationDelegate UIView: myView];
@selector ( removeFromSuperview ) ] ; [UIView setAnimationDidStopSelector: @ selector (removeFromSuperview)];

; myView.alpha = 0;

; [CommitAnimations UIView];

! Lo interesante de este enfoque es que myView podría ser una subclase de UIView ! Por lo tanto, puede ser una clase personalizada con nuestros propios mensajes y, como se dijo, fácilmente se puede llamar desde setAnimationDidStopSelector . Además, el setAnimationDidStopSelector selectores de acuerdo con los parámetros:

1
2
3
4
5
6
7
8
9
nil context : NULL ] ; [BeginAnimations UIView: contexto nada: NULL];
1.5 ] ; [UIView setAnimationDuration: 1,5];
UIViewAnimationCurveEaseInOut ] ; [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
myView ] ; [SetAnimationDelegate UIView: myView];
@selector ( myMessage : param1 : ) ] ; [UIView setAnimationDidStopSelector: @ selector (myMessage: param1:)];

; myView.alpha = 0;

; [CommitAnimations UIView];

En este ejemplo se puede extender a todos los casos aquí, donde hemos establecido un delegado, Atro no es un puntero a una instancia de un objeto.

Continuación ...

Cómo encontrar las imágenes y vistas en Interface Builder

Después de explicar cómo localizar nuestras cuerdas en Xcode , es fácil ver ahora cómo - mediante la aplicación de la misma técnica - para localizar y ver las imágenes / interfaces creados con Interface Builder.

Localizar los recursos gráficos

El proceso, como se mencionó, es el mismo, si tenemos una imagen ya está incluido en nuestros recursos, o insertar una nueva, y nos quieren "ubicar" - es decir, para manejar dos o más imágenes en función de los idiomas soportados - simplemente haga clic en el botón imagen de la derecha ( Adium.png en este ejemplo) y seleccione Obtener información:

Crear archivo localizable hacemos clic en la parte inferior izquierda.

Nosotros, haga clic en Agregar e introduzca la localización Italian :

Con el fin de obtener:

esattamente come accadeva con il testo: Nuestra imagen se mueve (física, una de las raras ocasiones en que ocurre nell'alberatura Xcode se refleja en el sistema de archivos) en carpetas virtuales English.lproj y Italian.lproj tal y como sucedió con el texto:

contiene una stessa versione dell'immagine. En este punto, cada una de las carpetas English.lproj y Italian.lproj contiene la misma versión de la imagen. Esta imagen es manipulada en Interface Builder, donde podremos ver - por defecto - la versión en Inglés.
En este punto, sólo sobrescribir uno (o ambos archivos Adium.png ) para obtener una ubicación de las imágenes "flash".

Localice el XIB archivos

Incluso las interfaces construidas con Interface Builder se puede encontrar en su totalidad, cuando se considere necesario. ) con interfaccia XIB , lo selezioniamo, scegliamo Get Info dal menu contestuale, rendiamo il file localizzabile, aggiungiamo la localizzazione in italiano: El procedimiento es idéntico al realizado con las capacidades gráficas: agregar un ViewController (por ejemplo, infoViewController ) XIB interfaz, que se selecciona, elige Obtener información en el menú contextual, dan la localizable archivo, añadir la localización italiano:

ViewController

Al hacer clic en Italiano o el italiano se abrirá Interface Builder! ) all'interno della classica cartella Classes . Esta vez, el sistema de archivos, te darás cuenta de que ha creado dos directorios ( English.lproj y Italian.lproj ) dentro de la carpeta de clases clásica. Ambos tienen sus archivos infoViewController.xib . La comodidad en este, resuelve con claridad en el código, y cuando vamos a una instancia de nuestro código de controlador vamos a tener una "limpia" de esta manera:

1
2
[ InfoViewController alloc ] ; InfoViewController * info = [InfoViewController alloc];
info.view ] ; [Self.view addSubview: info.view];

Como puedes ver no hay ni rastro de cualquier declaración relativa a la ubicación, totalmente administrado por el sistema. Las dos interfaces, por supuesto, puede ser completamente diferente, como lo son en efecto como dos archivos separados XIB.

Continuación ...

Fragmento muy breve: obtener la salida de una URL en Objective-C

Tal vez debería escribir "Muy, muy, fragmentos cortos", sin embargo, es una excelente y cómoda "truco" para mostrar lo que soy. Ejecución de los "dos" líneas de código se muestra a continuación, usted puede conseguir la salida de cualquier URL y manipularlo.

Continuación ...

10 fragmentos útiles para el iPhone de Apple

Ejecutar un método después de n segundos

Toda la familia performSelector es muy interesante y puede ser útil en multitud de casos. Su aplicación más simple y común es el siguiente:

1
2
3
4
5
@selector ( myMethod ) withObject : nil afterDelay : 3 ] ; [Self performSelector: @ selector (miMetodo) withObject: afterDelay nada: 3];
/ /
void ) myMethod { - (Void) {miMetodo
"Hello World!" ) ; NSLog (@ "Hello World!");
}

Sin embargo, consideran que el "timer" no es exacta. Este procedimiento, por lo tanto, se debe utilizar cuando no se requiere un "significativo" de precisión temporal.

Recuperar la versión de la

1
2
version = [ [ [ NSBundle mainBundle ] infoDictionary ] objectForKey : @ "CFBundleVersion" ] ; NSString * version = [[[ NSBundle mainBundle] infoDictionary] objectForKey: @ "CFBundleVersion"];
"versione = %@" , version ) ; NSLog (@ "Version =% @", la versión);

Sí, es cierto o verdadero?

e TRUE sono in pratica la stessa edentica cosa: Va a peinar el iPhone de Apple kernel puede darse cuenta de que YES , true , y TRUE son básicamente los Edentia lo mismo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/ / Definición de la SI
# Definición de SI (BOOL) 1
# Se define NO 0 (BOOL)

/ / Definición de la verdad
# Definición de una verdadera
# Define FALSO 0

/ / Definición de VERDADERO
# Si! Definida (VERDADERO)
# Define True 1
# Endif

# Si! Definida (FALSO)
# Define FALSO 0
# Endif

Al menos por ahora ...

Vibración

1
2
3
# Importar <AudioToolbox/AudioToolbox.h>
/ /
; AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

CGImageRef puntero de una UIImage

1
2
3
4
[ UIImage imageNamed : @ "LittleHeart.png" ] ; UIImage corazón * = [UIImage imageNamed: @ "LittleHeart.png"];
heart CGImage ] ; CGImageRef imagen = [CGImage corazón];
/ / La imagen ahora pueden ser "trama" en una CGContextRef
CGRect ) { 0 , 0 , 100 , 100 } , image ) ; CGContextDrawImage (c, (CGRect) {0, 0, 100, 100}, imagen);

Animaciones

1
2
3
4
5
nil context : NULL ] ; [BeginAnimations UIView: contexto nada: NULL];
1.5 ] ; [UIView setAnimationDuration: 1,5];
UIViewAnimationCurveEaseInOut ] ; [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
/ / ...
; [CommitAnimations UIView];

NSLog

1
2
3
"NSString object %@ " , myString ) ; NSLog (@ "NSString objeto% @", MyString);
"Float: %f " , myFloat ) ; NSLog (@ "float:% f", myFloat);
"Integer: %i " , myInt ) ; NSLog (@ "Integer:% i", myInt);

Conversor de RGB UIColor

1
# Definición de RGBA (r, g, b, a) [UIColor colorWithRed: verde r/255.0: azul g/255.0: b/255.0 alfa: a]

Paso de parámetros a un NSTimer

Aprovechando el parámetro userInfo puede enviar un puntero a un objeto a nuestro método invocado por temporizador.

1
2
3
4
5
6
7
8
9
10
11
12
13
scheduledTimerWithTimeInterval : 1 target : self selector : @selector ( timerMethod ) userInfo : objectPointer repeats : YES ] ; [ NSTimer scheduledTimerWithTimeInterval: un objetivo: selector de auto: @ selector (timerMethod) userInfo: repite objectPointer: YES];

/ / ...

void ) timerMethod : ( NSTimer * ) timer { - (Void) timerMethod: ( NSTimer *) {contador
/ / Recuperar el puntero a mi objeto
timer userInfo ] ; objectPointer = [temporizador userInfo];
/ / O
myMethod ] ; [[Timer userInfo] miMetodo];
[ [ timer userInfo ] myProperty ] ; int a = [[temporizador userInfo] myProperty];
/ / ¿Qué es la misma
[ objectPointer myProperty ] ; int a = [objectPointer myProperty];
}

Tiempo de funcionamiento

Esta es una forma sencilla de calcular el tiempo necesario para comprobar la velocidad de la ejecución del código:

1
2
3
4
; CFAbsoluteTime initialTime CFAbsoluteTimeGetCurrent = ();
/ / ... cruz
; CFAbsoluteTime finalTime CFAbsoluteTimeGetCurrent = ();
"Tempo trascorso %f" , finalTime - initialTime ) ; NSLog (@ "f% transcurrido el tiempo", finalTime - initialTime);

Continuación ...

Objective-C: propiedades de exponer en una clase

Me gustaría mostrar y discutir algunos ejemplos acerca de cómo agregar y manipular las propiedades de la clase Objective-C. : Un ejemplo clásico es, precisamente, lo siguiente, en la definición de nuestra clase de interfaz define dos propiedades nome y cognome :

1
2
3
4
5
6
7
8
9
10
11
/ / MyClass.h
# Importar <Foundation/Foundation.h>

NSObject { @ Interface MyClass: NSObject {
nome; NSString * nombre;
cognome; NSString * nombre;
}

retain ) NSString * nome; @ Propiedad (retener) NSString * nombre;
retain ) NSString * cognome; @ Propiedad (retener) NSString * nombre;
@ End

e setter usati rispettivamente per leggere ed impostare le nostre due proprietà: En el archivo de la aplicación de la instrucción INSERT @synthesize lo que Xcode se producen para nosotros los métodos getter y setter , respectivamente, que se utiliza para leer y establecer las dos propiedades:

1
2
3
4
5
6
7
8
/ / MyClass.m
# Import "MyClass.h"

@ Implementación MyClass

@ Name Sintetizar y apellidos;

@ End

, possiamo scrive: Cuando usted va a utilizar la clase MyClass , que es cuando istanziaremo un objeto de tipo MyClass , se puede escribir:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/ / Cualquier otra clase, como AppDelegate
/ / En el archivo. H
# Importar <UIKit/UIKit.h>
# Import "MyClass.h"

@ Clase TestViewController;

NSObject <UIApplicationDelegate> { @ Interface TesAppDelegate: NSObject {<UIApplicationDelegate>
UIWindow * ventana;
* TestViewController ViewController;

MyClass * miClase;
}

/ / En el archivo. M
MyClass alloc ] ; myClass = [MyClass alloc];
"Giovambattista" ; miaClasse.nome @ = "Giovambattista";
"miaClasse.nome = %@" , miaClasse.nome ) ; NSLog (@ "miaClasse.nome =% @", miaClasse.nome);

O, lo que es equivalente a:

1
2
3
/ / Siempre en la M archivo.
@ "Undolog" ] ; [SetNome myClass: @ "Undolog"];
"miaClasse.nome = %@" , [ miaClasse nome ] ) ; NSLog (@ "miaClasse.nome =% @", [nombre miClase]);

Hasta aquí todo bien. Sin embargo, podría inducir a error a la equivalencia de las "variables" internas (ivar) con el nombre de la propiedad en sí. Para entender la diferencia, proponer de nuevo lo mismo que hacerlo fuera, esta vez, la @synthesize . . Ahora, por lo tanto, debemos tener cuidado en escribir los métodos getter y setter . Para enfatizar aún más las diferencias, se cambie el nombre de las variables internas mediante la inserción de un guión bajo delante del nombre. Sin embargo, vemos el código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Importar <Foundation/Foundation.h>

NSObject { @ Interface MyClass: NSObject {
_nome; NSString * _name;
_cognome; NSString * _cognome;
}

NSString * ) nome; // get - ( NSString *) Nombre; / / obtener
NSString * ) cognome; // get - ( NSString *) Nombre; / / obtener

void ) setNome : ( NSString * ) stringaIngresso; // set - (Void) setNome: ( NSString *) stringaIngresso; / / establecer
void ) setCognome : ( NSString * ) stringaIngresso; // set - (Void) setCognome: ( NSString *) stringaIngresso; / / establecer

@ End

. A diferencia de los punteros antes de las variables internas (incapsultate) se han convertido en _nome y _cognome . . @property è scomparso, in quanto non serve più. Además hay cuatro definiciones de los métodos que representan nuestra get y set . @property ha desaparecido, ya que no necesita más.
Vemos el archivo de implementación MyClass.m :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Import "MyClass.h"

@ Implementación MyClass

/ / Obtener un "nombre"
NSString * ) nome { - ( NSString *) Nombre {
_name Retorno;
}
/ / Set para "nombre"
void ) setNome : ( NSString * ) stringaIngresso { - (Void) setNome: ( NSString *) {stringaIngresso
_name StringaIngresso =;
}

/ / Obtener de "apellido"
NSString * ) cognome { - ( NSString *) Nombre {
_cognome retorno;
}
/ / Set para "apellido"
void ) setCognome : ( NSString * ) stringaIngresso { - (Void) setCognome: ( NSString *) {stringaIngresso
_cognome = stringaIngresso;
}

@ End

Escrito como una clase se puede utilizar exactamente igual que el anterior, a saber:

1
2
3
4
5
6
7
8
MyClass alloc ] ; myClass = [MyClass alloc];
"Giovambattista" ; miaClasse.nome @ = "Giovambattista";
"miaClasse.nome = %@" , miaClasse.nome ) ; NSLog (@ "miaClasse.nome =% @", miaClasse.nome);

/ / O, lo que equivale a:

@ "Undolog" ] ; [SetNome myClass: @ "Undolog"];
"miaClasse.nome = %@" , [ miaClasse nome ] ) ; NSLog (@ "miaClasse.nome =% @", [nombre miClase]);

e set , evidenziando – anche con l'aggiunta dell'underscore – le differenze tra il nome della proprietà e la sua ivar interna _nome . En el nivel de abandono educativo @synthesize nos obligó a escribir "su propia" métodos de get y set , destacando - incluso con la adición dell'underscore - las diferencias entre el nombre de la propiedad y su ivar interna _nome .
permette un reale controllo del dato prima della sua impostazione (o prima della sua lettura) e quindi un reale incapsulamento per proteggere la variabile interna. En el nivel funcional del uso personal de los métodos de get y set permite un control real de los datos antes de su puesta (o antes de su lectura) y un encapsulado real para proteger a la variable interna.
Por ejemplo, sería posible para impedir el paso de cadenas vacías a la propiedad nome :

1
2
3
4
void ) setNome : ( NSString * ) stringaIngresso { - (Void) setNome: ( NSString *) {stringaIngresso
stringaIngresso == @ "" ) stringaIngresso = @ "senza nome" ; if (@ stringaIngresso == "") @ stringaIngresso = "sin nombre";
_name StringaIngresso =;
}

Otra variación

Si desea utilizar las variables internas con el guión bajo delante (que rpoviene Adobe ActionScript puede ser utilizado también) no es necesario abandonar el uso de la directiva @synthesize . Xcode permite "fusionar" los métodos mencionados anteriormente:

1
2
_nome; Sintetizar @ name = _name;
_cognome; @ Name = Sintetizar _cognome;

. Al hacerlo, puede usar el puntero para las personas internamente _nome ", resumió" - en el exterior - como una propiedad de nome . e setter , è vero anche che lo fa solo se non li trova, quindi se desiderate “implementare” un vostro metodo di getter e/o setter potete farlo anche se avete usato la direttiva @synthesize . Por otra parte, es cierto que el uso de @synthesize produce la generación de métodos automáticos (mensajes) de getter y setter , también es cierto que si no las encuentra, por lo que si quieren "aplicar" un método para su getter y / o setter que usted puede hacer esto incluso si ha utilizado la directiva @synthesize .

Las asignaciones de memoria

En los ejemplos anteriores he omitido algunos detalles importantes para una implementación real. En primer lugar, no han mostrado ningún método init() , útil para la inicialización de objetos y valores por defecto. Por otra parte, está la adición de un método dealloc() :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/ / Archivo MyClass.m
# Import "MyClass.h"

@ Implementación MyClass

id ) init { - (Id) {init
self = [ super init ] ) { if (self = [super init]) {
"Nome preimpostato" ; _name @ = "Nombre del ajuste";
"Cognome preimpostato" ; _cognome @ = "Nombre del ajuste";
}
cambio sí;
}

void ) dealloc { - (Void) {dealloc
; [_name Release];
; [_cognome Release];
; [Super dealloc];
}

NSString * ) nome { - ( NSString *) Nombre {
_name Retorno;
}
void ) setNome : ( NSString * ) stringaIngresso { - (Void) setNome: ( NSString *) {stringaIngresso
stringaIngresso == @ "" ) stringaIngresso = @ "senza nome" ; if (@ stringaIngresso == "") @ stringaIngresso = "sin nombre";
_name StringaIngresso =;
}

NSString * ) cognome { - ( NSString *) Nombre {
_cognome retorno;
}
void ) setCognome : ( NSString * ) stringaIngresso { - (Void) setCognome: ( NSString *) {stringaIngresso
_cognome = stringaIngresso;
}

@ End

, etc… En el futuro veremos entonces los detalles de las propiedades readonly , retain , etc ... :)

Continuación ...

Explorador o navegador de tu móvil?

Nuestro sitio web es ahora sólo se muestra por los PC. Con la difusión de la telefonía móvil, gracias al iPhone de Apple, para acceder al sitio o blog es cada vez más los trabajos realizados por una variedad de dispositivos móviles. Por lo tanto, necesitamos saber cuántos Web Developer interceptar e identificar los diferentes "agentes", es decir, el medio por el cual un usuario está viendo (navegación) y nuestras páginas.

Continuación ...

Apple iPhone: Crear un botón de activación personalizado

non funzionano quando un UIButton è impostato in modalità UIButtonTypeCustom ! Los estados UIControlStateSelected o UIControlStateHighlighted no funciona cuando hay un UIButton modo se establece UIButtonTypeCustom ! O más bien, no funcionan (porque reservado para otro tipo de botón), por ejemplo, para crear un botón de dos estados: nota de palanca. Si hemos creado dos imágenes (y stato2.png stato1.png) para nuestro botón, se puede proceder de la siguiente manera:

1
2
3
/ / Los archivos de cabecera que se crea una variable global para usaremo
/ / Comprobar la palanca se
ToggleFlag BOOL;

Ahora vamos a crear nuestro botón:

1
2
3
4
5
6
7
8
9
/ / Creamos un botón y lo colocamos inicialmente en el estado "stato1.png"
/ / Editar initWithFrame: (CGRect) {} 100,100,50,50 con la ubicación y
/ / Tamaño de la imagen ha
; toggleFlag = YES;
[ [ UIButton buttonWithType : UIButtonTypeCustom ] initWithFrame : ( CGRect ) { 100 , 100 , 50 , 50 } ] ; UIButton ToggleButton * = [[UIButton buttonWithType: UIButtonTypeCustom] initWithFrame: (CGRect) {100, 100, 50, 50}];
@ "" forState : UIControlStateNormal ] ; [ToggleButton setTitle: @ "" Forst: UIControlStateNormal];
[ UIImage imageNamed : @ "stato1.png" ] forState : UIControlStateNormal ] ; [ToggleButton setBackgroundImage: [UIImage imageNamed: @ "stato1.png"] Forst: UIControlStateNormal];
self action : @selector ( onToggle : ) forControlEvents : UIControlEventTouchUpInside ] ; [AddTarget ToggleButton: acción de auto: @ selector (onToggle:) forControlEvents: UIControlEventTouchUpInside];
toggleButton ] ; [Self.view addSubview: ToggleButton];

Al hacer clic en el botón se envía un mensaje a gestionar onToggle :

1
2
3
4
5
6
7
void ) onToggle : ( id ) sender { - (Void) onToggle: (id) {remitente
/ / Recuperar puntero a UIButton
( UIButton * ) sender; UIButton buttonClicked * = (UIButton *) del remitente;
/ / Ejecutar Toogle
toggleFlag = toggleFlag!;
[ UIImage imageNamed : ( toggleFlag ) ? @ "stato1.png" : @ "stato2.png" ] forState : UIControlStateNormal ] ; [ButtonClicked setBackgroundImage: [UIImage imageNamed: (toggleFlag) @ "Stato1.png" @ "stato2.png"] Forst: UIControlStateNormal];
}

Continuación ...

Fragmento muy breve: la transmisión de archivos mp3 en el iPhone de Apple

Una alternativa muy simple de ejecutar una secuencia de un archivo mp3 en el iPhone de Apple podría ser:

Continuación ...

Objective-C: NSLog () de C struct

o CGPoint , ad esempio. La sintaxis NSLog(@"%@", ... ); que funciona y se utiliza para obtener información sobre los objetos, pero no funciona en C tipos de datos tales como la estructura CGRect o CGPoint , por ejemplo. o NSStringFromCGPoint : Para aprovechar las ventajas de NSLog(@"%@", ... ); incluso en las estructuras de C-estilo se puede confiar en las funciones de conversión como NSStringFromCGRect() o NSStringFromCGPoint :

1
2
3
4
5
CGRect ) { 10 , 20 , 30 , 40 } ; CGRect mioRect = (CGRect) {10, 20, 30, 40};
CGPoint ) { 32 , 64 } ; CGPoint mioPoint = (CGPoint) {32, 64};
/ /
"Info rettangolo: %@" , NSStringFromCGRect ( mioRect ) ) ; NSLog (@ "rectángulo Info:% @", NSStringFromCGRect (mioRect));
"Info point: %@" , NSStringFromCGPoint ( mioPoint ) ) ; NSLog (@ "punto de información:% @", NSStringFromCGPoint (mioPoint));

En concreto, es posible mejorar este procedimiento habla de pequeñas macros útiles, como:

1
# Definir NSLogRect (rect) NSLog (@ "0.0fx% s (% 0.0f,% 0.0f)% 0.0f%", # rect, rect.origin.x, rect.origin.y, rect.size.width , rect.size.height)

O:

1
2
3
4
# Definir NSLogCGPoint (punto) NSLog (@ "% s (% 0.0f,% 0.0f)", # punto.x punto, Point.y)

CGPoint ) { 32 , 64 } ; CGPoint mioPoint = (CGPoint) {32, 64};
; NSLogCGPoint (mioPoint);

Que dará como resultado:

1
32 , 64 ) mioPoint: (32, 64)

Continuación ...