Catégorie 'Mobile'


iPad: gérer vos écrans de démarrage

Sur l'Apple iPhone et iPod nous permet de gérer un seul fichier image lors du chargement de l'application, le fichier Default.png . Sur l'Apple iPad, cependant, les différents dell'orientamente de gestion nécessite l'adoption de plusieurs fichiers image, pour s'assurer que vous voyez l'écran de démarrage all'orientamente correct pour le périphérique. Lorsque l'application démarre, comme ce fut le cas pour l'iPhone, il n'est pas possible de parler code pour "étonnant" dans cette orientation de l'appareil. Heureusement, il a été introduit dans le chargement automatique des fichiers spéciaux en fonction de l'orientation:

Les fichiers sont actuellement pris en charge, en plus de la classique Default.png recommandent pas que vous utilisez comme elle est redimensionnée et déformée en fonction de l'orientation sont les suivants:

  • 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. Les versions PortraitUpsideDown , LandscapeLeft et LandscapeRight peuvent être utilisés pour déterminer Portrait View et vers celui-ci.

Pour l'application a commencé, alors, comme recommandé par Apple, il est bon de "repenser" - le cas échéant - nos opinions agissant dans application:didFinishLaunchingWithOptions .

Suite ...

setAnimationDidStopSelector: les différents usages et avancées

Dans la plupart des cas, soit parce que nous sommes habitués à ou parce que nous avons vu dans les didacticiels et, dans certains textes, nous utilisons le setAnimationDidStopSelector de cette façon:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
nil context : NULL ] ; [UIView beginAnimations: contexte néant: NULL];
1.5 ] ; [UIView setAnimationDuration: 1,5];
UIViewAnimationCurveEaseInOut ] ; [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
self ] ; [UIView setAnimationDelegate: self];
@selector ( removeView ) ] ; [UIView setAnimationDidStopSelector: @ selector (removeView)];

; myView.alpha = 0;

; [UIView commitAnimations];

/ /

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

come delegato e tramite la setAnimationDidStopSelector gli invia un messaggio removeView quando l'animazione è terminata. Dans le code ci-dessus, le setAnimationDelegate définit self en tant que délégué et par setAnimationDidStopSelector lui envoie un message removeView lorsque l'animation est terminée. Le code lui-même est correct, cependant, fait usage d'une définition de message ( removeView ) qui pourraient être omis. Maintenant, voici le même code, avec le même effet, sans que le message removeView :

1
2
3
4
5
6
7
8
9
nil context : NULL ] ; [UIView beginAnimations: contexte néant: NULL];
1.5 ] ; [UIView setAnimationDuration: 1,5];
UIViewAnimationCurveEaseInOut ] ; [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
myView ] ; [UIView setAnimationDelegate: myView];
@selector ( removeFromSuperview ) ] ; [UIView setAnimationDidStopSelector: @ selector (removeFromSuperview)];

; myView.alpha = 0;

; [UIView commitAnimations];

! La chose intéressante à propos de cette approche est que myView pourrait être une sous-classe d'une UIView ! Il peut donc être une classe personnalisée avec nos propres messages et, comme l'explique, tranquillement appelable de setAnimationDidStopSelector . En outre, le setAnimationDidStopSelector accepte les sélecteurs avec les paramètres:

1
2
3
4
5
6
7
8
9
nil context : NULL ] ; [UIView beginAnimations: contexte néant: NULL];
1.5 ] ; [UIView setAnimationDuration: 1,5];
UIViewAnimationCurveEaseInOut ] ; [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
myView ] ; [UIView setAnimationDelegate: myView];
@selector ( myMessage : param1 : ) ] ; [UIView setAnimationDidStopSelector: @ selector (myMessage: param1 :)];

; myView.alpha = 0;

; [UIView commitAnimations];

Cet exemple peut être étendu à tous les cas ici où nous nous sommes fixés un délégué, Grim n'est pas un pointeur vers une instance d'un objet quelconque.

Suite ...

Comment localiser des images et des vues de Interface Builder

Après avoir expliqué comment localiser nos chaînes dans Xcode , voyons maintenant combien est simple - en appliquant la même technique - pour localiser et visualiser des images / interfaces construites avec Interface Builder.

Repérez les ressources graphiques

Le processus, comme mentionné, est le même, si nous avons une image déjà insérée dans nos ressources, ou nous insérer une nouvelle, et nous voulons "localiser" - qui consiste à gérer deux images ou plus en fonction des langues prises en charge - il suffit de cliquer sur le bouton l'image de droite ( Adium.png dans cet exemple) et sélectionnez Get Info:

Créer un fichier clic Localizable en bas à gauche.

Cliquez sur Ajouter, puis insérez Localisation Italian :

Afin d'obtenir:

esattamente come accadeva con il testo: Notre image est déplacée (physiquement, l'une des rares fois où cela arrive nell'alberatura Xcode est reflétée dans le système de fichiers) dans le cadre des dossiers virtuels English.lproj et Italian.lproj comme ce fut le cas avec le texte:

contiene una stessa versione dell'immagine. A ce stade, chacun des dossiers English.lproj et Italian.lproj contient une même version de l'image. Cette image est manipulée dans Interface Builder, où nous verrons - par défaut - la version anglaise.
À ce stade, juste écraser une (ou les deux fichiers Adium.png ) pour permettre une localisation des images "Flash".

Localisez le fichier XIB

Même les interfaces construites avec Interface Builder peuvent être localisées dans leur intégralité, lorsque cela est jugé nécessaire. ) con interfaccia XIB , lo selezioniamo, scegliamo Get Info dal menu contestuale, rendiamo il file localizzabile, aggiungiamo la localizzazione in italiano: La procédure est identique à celle réalisée avec les ressources graphiques: ajouter un ViewController (par exemple infoViewController ) Interface XIB, nous sélectionnons, choisissez Lire les informations dans le menu contextuel, nous faisons les fichiers localisables, ajouter la localisation en italien:

ViewController

En cliquant Inglese ou en anglais ouvrira Interface Builder! ) all'interno della classica cartella Classes . Cette fois-ci, le système de fichiers, vous remarquerez que vous avez créé deux dossiers ( English.lproj et Italian.lproj ) dans le dossier Classes classique. Les deux auront leur fichier infoViewController.xib . Le confort dans ce domaine, résolu évident dans le code, et quand nous allons instancier notre code du contrôleur, vous aurez un "propre" comme ceci:

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

Comme vous pouvez le voir il n'ya aucune trace de toute déclaration concernant l'emplacement, entièrement géré par le système. Les deux interfaces, bien sûr, peut être complètement différent, car ils sont à tous les effets que les deux fichiers XIB séparé.

Suite ...

Très court extrait: obtenir la sortie d'une URL en Objective-C

Je devrais peut-être écrire "Très très très, court extrait", mais il est un excellent et pratique "truc" que je suis sur le point de montrer. En exécutant les lignes «deux» du code ci-dessous, vous pouvez obtenir la sortie d'une URL et de le manipuler.

Suite ...

10 extraits utiles pour Apple iPhone

Exécuter une méthode après n secondes

La famille entière performSelector est vraiment intéressant et peut être utile dans une multitude de cas. Son application la plus simple et la plus courante est la suivante:

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

Cependant, considérer que le "timer" n'est pas exact. Cette procédure devrait donc être utilisée quand il n'est pas invité à une précision temporelle "significatif".

Récupérer la version de l'application

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

Oui, c'est vrai ou faux?

e TRUE sono in pratica la stessa edentica cosa: Va passer au peigne fin le Apple iPhone du noyau, vous pouvez vous rendre compte que YES , true et TRUE edentica sont essentiellement la même chose:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/ / Définition du OUI
# Définir OUI (bool) 1
# Définir NO (bool) 0

/ / Définition de la vraie
# Définir true 1
# Définir false 0

/ / Définition de TRUE
# Si! Défini (TRUE)
# Définir TRUE 1
# Endif

# Si! Défini (FAUX)
# Définir FALSE 0
# Endif

Au moins pour l'instant ...

Brouter

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

CGImageRef du pointeur d'une UIImage

1
2
3
4
[ UIImage imageNamed : @ "LittleHeart.png" ] ; UIImage * heart = [UIImage imageNamed: @ "LittleHeart.png"];
heart CGImage ] ; CGImageRef image = [CGImage coeur];
/ / L'image peut maintenant être "pixellisé" sur un CGContextRef
CGRect ) { 0 , 0 , 100 , 100 } , image ) ; CGContextDrawImage (c, (CGRect) {0, 0, 100, 100}, image);

Animations

1
2
3
4
5
nil context : NULL ] ; [UIView beginAnimations: contexte néant: NULL];
1.5 ] ; [UIView setAnimationDuration: 1,5];
UIViewAnimationCurveEaseInOut ] ; [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
/ / ...
; [UIView commitAnimations];

NSLog

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

Convertisseur RGB à UIColor

1
# Définir RGBA (r, g, b, a) [UIColor colorWithRed: r/255.0 vert: bleu g/255.0: b/255.0 alpha: a]

Transmission de paramètres à une NSTimer

Profitant du paramètre userInfo vous pouvez envoyer un pointeur vers un objet à la méthode invoquée par notre chronomètre.

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: 1 cible: self selector: @ selector (timerMethod) userInfo: répète objectPointer: YES];

/ / ...

void ) timerMethod : ( NSTimer * ) timer { - (Void) timerMethod: ( NSTimer *) timer {
/ / Récupérer le pointeur de mon objet
timer userInfo ] ; objectPointer = [timer userInfo];
/ / Ou
myMethod ] ; [[Timer userInfo] myMethod];
[ [ timer userInfo ] myProperty ] ; int a = [[timer userInfo] myProperty];
/ / Quel est le même
[ objectPointer myProperty ] ; int a = [objectPointer myProperty];
}

Temps d'exécution

Voici une façon simple de calculer court laps de temps nécessaire pour vérifier la vitesse d'exécution du code:

1
2
3
4
; CFAbsoluteTime initialTime CFAbsoluteTimeGetCurrent = ();
/ / ... Code
; CFAbsoluteTime finalTime CFAbsoluteTimeGetCurrent = ();
"Tempo trascorso %f" , finalTime - initialTime ) ; NSLog (@ "Temps écoulé% f", finalTime - initialTime);

Suite ...

Objective-C: exposer des propriétés dans une classe

Je voudrais montrer et de discuter quelques exemples sur la façon d'ajouter et de manipuler une propriété dans la classe Objective-C. : Un exemple classique est, précisément, comme suit, dans la définition de notre interface de classe, nous définissons deux propriétés nome et cognome :

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

NSObject { @ Interface MaClasse: NSObject {
nome; NSString * name;
cognome; NSString * name;
}

retain ) NSString * nome; @ Property (retain) NSString * name;
retain ) NSString * cognome; @ Property (retain) NSString * name;
@ Fin

e setter usati rispettivamente per leggere ed impostare le nostre due proprietà: Dans le fichier de mise en œuvre, nous insérons la déclaration @synthesize afin que Xcode produire pour nous les méthodes getter et setter utilisés pour obtenir et mettre en place nos deux propriétés:

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

@ Mise en œuvre MyClass

@ Nom de synthétiser, nom de famille;

@ Fin

, possiamo scrive: Lorsque vous allez utiliser notre classe MyClass , c'est à dire lorsque istanziaremo un objet de type MyClass , nous pouvons écrire:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/ / Tout autre classe, comme appDelegate
/ / Dans le fichier. H
# Import <UIKit/UIKit.h>
# Import "MyClass.h"

@ Classe TestViewController;

NSObject <UIApplicationDelegate> { @ Interface TesAppDelegate: NSObject {<UIApplicationDelegate>
UIWindow * fenêtre;
TestViewController * viewController;

MyClass * myClass;
}

/ / Dans le fichier. M
MyClass alloc ] ; myClass = [MyClass alloc];
"Giovambattista" ; miaClasse.nome = @ "Giovambattista";
"miaClasse.nome = %@" , miaClasse.nome ) ; NSLog (@ "miaClasse.nome =% @", miaClasse.nome);

Or, ce qui est équivalent à:

1
2
3
/ / Toujours dans le fichier. M
@ "Undolog" ] ; [MaClasse setNome: @ "Undolog"];
"miaClasse.nome = %@" , [ miaClasse nome ] ) ; NSLog (@ "miaClasse.nome =% @", [myClass nom]);

Jusqu'ici tout va bien. Cependant, il pourrait induire en erreur l'équivalence des "variabli" interne (Ivar) avec le nom de la propriété elle-même. Pour comprendre la différence, proposer à nouveau la même chose que faire sans, cette fois, l' @synthesize . . Maintenant, donc, nous devrions nous prendre pour écrire les méthodes getter et setter . Pour souligner davantage les différences, rinominerò les variables internes en insérant un tiret devant le nom. Mais voyons le code suivant:

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

NSObject { @ Interface MaClasse: NSObject {
_nome; NSString * _Name;
_cognome; NSString * _cognome;
}

NSString * ) nome; // get - ( NSString *) nom; / / récupère
NSString * ) cognome; // get - ( NSString *) nom; / / récupère

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

@ Fin

. Contrairement aux précédents pointeurs vers des variables internes (incapsultate) sont devenus _nome et _cognome . . @property è scomparso, in quanto non serve più. En outre, il ya quatre définitions de méthodes qui représentent notre get et set . @property a disparu, que vous n'avez plus besoin.
Nous voyons le fichier mise en œuvre 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"

@ Mise en œuvre MyClass

/ / Obtenir un «nom»
NSString * ) nome { - ( NSString *) nom {
_NAME Retour;
}
/ / Set pour "nom"
void ) setNome : ( NSString * ) stringaIngresso { - (Void) setNome: ( NSString *) {stringaIngresso
_Name = StringaIngresso;
}

/ / Obtenir de "nom de famille"
NSString * ) cognome { - ( NSString *) nom {
_cognome retour;
}
/ / Set pour "nom de famille"
void ) setCognome : ( NSString * ) stringaIngresso { - (Void) setCognome: ( NSString *) {stringaIngresso
_cognome = stringaIngresso;
}

@ Fin

Une classe de manière écrite peut être utilisé exactement comme le précédent, à savoir:

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);

/ / Ou, ce qui est équivalent à:

@ "Undolog" ] ; [MaClasse setNome: @ "Undolog"];
"miaClasse.nome = %@" , [ miaClasse nome ] ) ; NSLog (@ "miaClasse.nome =% @", [myClass nom]);

e set , evidenziando – anche con l'aggiunta dell'underscore – le differenze tra il nome della proprietà e la sua ivar interna _nome . Au niveau de la négligence éducative @synthesize nous a forcés à écrire des méthodes "vous-même" get et set , mettant en évidence - même avec l'ajout dell'underscore - la différence entre le nom de la propriété et de son interne Ivar _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. Au niveau fonctionnel l'utilisation de méthodes personnelles get et set permet un contrôle réel des données avant sa création (ou avant de le lire), puis un véritable encapsulation pour protéger la variable interne.
Par exemple, il serait possible d'empêcher le passage des chaînes vides à la propriété nome :

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

Autre variante

Si vous souhaitez utiliser les variables internes avec le trait de soulignement à l'avant (qui rpoviene de Adobe ActionScript peut être utilisé aussi bien) n'ont pas besoin de renoncer à l'utilisation de la directive @synthesize . Xcode permet de "fusionner" les méthodes décrites ci-dessus:

1
2
_nome; @ Synthétiser name = _Name;
_cognome; @ Synthétiser name = _cognome;

. Ce faisant, nous pourrions utiliser le pointeur pour l'intérieur _nome ", résume" - à l'extérieur - comme une propriété 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 . En outre, s'il est vrai que l'utilisation de @synthesize produit les méthodes de génération automatique (messages) de getter et setter , il est également vrai qu'il ne le fait que si vous ne les trouvez pas, si vous voulez "mettre en oeuvre" une méthode pour votre getter et / ou setter peut le faire même si vous avez utilisé la directive @synthesize .

les allocations de mémoire

Dans les exemples ci-dessus j'ai omis quelques détails importants pour une mise en œuvre réelle. Tout d'abord, je n'ai pas présenté une méthode init() , utile pour l'initialisation des objets et valeurs par défaut. En outre, il manque de l'ajout d'une méthode 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
MyClass.m / / File
# Import "MyClass.h"

@ Mise en œuvre MyClass

id ) init { - (Id) {initialisation
self = [ super init ] ) { if (self = [super init]) {
"Nome preimpostato" ; _Name = @ "Preset Name»;
"Cognome preimpostato" ; _cognome = @ "Preset Name»;
}
retourner soi-même;
}

void ) dealloc { - (Void) dealloc {
; [_Name De presse];
; [_cognome De presse];
; [Super dealloc];
}

NSString * ) nome { - ( NSString *) nom {
_NAME Retour;
}
void ) setNome : ( NSString * ) stringaIngresso { - (Void) setNome: ( NSString *) {stringaIngresso
stringaIngresso == @ "" ) stringaIngresso = @ "senza nome" ; if (@ stringaIngresso == "") stringaIngresso = @ "no name";
_Name = StringaIngresso;
}

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

@ Fin

, etc… Dans l'avenir, nous allons voir les détails sur la propriété readonly , retain , etc ... :)

Suite ...

Browser ou navigateur mobile?

Notre site web est maintenant non seulement affiché par les PC. Avec la propagation de la téléphonie mobile, principalement grâce à l'iPhone d'Apple, l'accès au site ou blog est de plus en plus fabriqués à partir de dispositifs mobiles de différents types. Il est donc nécessaire de savoir combien interception Web Developer et d'identifier les différents «agents», c'est-à-dire les moyens par lesquels les points de vue d'un utilisateur (voile) nos pages.

Suite ...

Apple iPhone: créer un bouton à bascule sur mesure

non funzionano quando un UIButton è impostato in modalità UIButtonTypeCustom ! Les Etats UIControlStateSelected ou UIControlStateHighlighted fonctionne pas quand un UIButton est réglé en mode UIButtonTypeCustom ! Ou plutôt, ne fonctionnent pas comme ils le devraient (parce que réservé à d'autres types de bouton), par exemple pour créer un bouton à deux états: note bascule. Si nous avons créé deux images (stato1.png et stato2.png) pour notre bouton, nous pouvons procéder de cette façon:

1
2
3
/ / Le fichier d'en-tête, nous créons une variable globale qui usaremo pour
/ / Vérifier la bascule étaient
ToggleFlag BOOL;

Maintenant, nous allons créer notre bouton:

1
2
3
4
5
6
7
8
9
/ / Creaiamo un bouton et on le place d'abord dans le "stato1.png"
/ / Modifier initWithFrame: (CGRect) {} 100,100,50,50 avec l'emplacement et
/ / La taille de votre image spéculaire
; toggleFlag = OUI;
[ [ UIButton buttonWithType : UIButtonTypeCustom ] initWithFrame : ( CGRect ) { 100 , 100 , 50 , 50 } ] ; UIButton * ToggleButton = [[UIButton buttonWithType: UIButtonTypeCustom] initWithFrame: (CGRect) {100, 100, 50, 50}];
@ "" forState : UIControlStateNormal ] ; [ToggleButton setTitle: @ "" pourState: UIControlStateNormal];
[ UIImage imageNamed : @ "stato1.png" ] forState : UIControlStateNormal ] ; [ToggleButton setBackgroundImage: [UIImage imageNamed: @ "stato1.png"] pourState: UIControlStateNormal];
self action : @selector ( onToggle : ) forControlEvents : UIControlEventTouchUpInside ] ; [ToggleButton addTarget: action d'auto: @ selector (onToggle :) forControlEvents: UIControlEventTouchUpInside];
toggleButton ] ; [Self.view addSubview: ToggleButton];

Lorsque vous cliquez sur le bouton sera envoyé un message manipulé par onToggle :

1
2
3
4
5
6
7
void ) onToggle : ( id ) sender { - (Void) onToggle: (id) sender {
/ / Récupérer pointeur vers UIButton
( UIButton * ) sender; ButtonClicked UIButton * = (UIButton *) sender;
/ / Je lance bascule,
toggleFlag = toggleFlag!;
[ UIImage imageNamed : ( toggleFlag ) ? @ "stato1.png" : @ "stato2.png" ] forState : UIControlStateNormal ] ; [? ButtonClicked setBackgroundImage: [UIImage imageNamed: (toggleFlag) @ "Stato1.png": @ "stato2.png"] pourState: UIControlStateNormal];
}

Suite ...

Très court extrait: lecture de fichiers MP3 sur l'iPhone d'Apple

Une alternative vraiment facile à exécuter un flux d'un fichier mp3 sur l'iPhone d'Apple pourrait être:

Suite ...

Objective-C: NSLog () sur C struct

o CGPoint , ad esempio. La syntaxe NSLog(@"%@", ... ); fonctionne et est utilisé pour obtenir des informations sur les objets, mais ne fonctionne pas sur les types de données C comme struct CGRect ou CGPoint , par exemple. o NSStringFromCGPoint : Pour profiter NSLog(@"%@", ... ); également sur ​​struct C-type peut se pencher sur les fonctions de conversion telles que NSStringFromCGRect() ou 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 (@ "Info rectangle:% @", NSStringFromCGRect (mioRect));
"Info point: %@" , NSStringFromCGPoint ( mioPoint ) ) ; NSLog (@ "point Info:% @", NSStringFromCGPoint (mioPoint));

Plus précisément, vous pouvez affiner la procédure scrivendosi de petites macros qui sont utiles comme:

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

Ou:

1
2
3
4
# Définir NSLogCGPoint (points) NSLog (@ "% s: (% 0.0f, 0.0f%)", # point.x point point.y)

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

Cela donnera en sortie:

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

Suite ...