C'est un programme que j'écris (moi-même, par opposition à copier quelqu'un d'autre et donc pas d'apprentissage) dans le cadre de la courbe d'apprentissage ObjectiveC et Cocoa. Je veux dessiner des formes simples sur un NSView (en le limitant aux ovales et aux rectangles pour l'instant). L'idée est que j'enregistre chaque NSBezierPath sur un NSMutableArray afin que je puisse aussi étudier/implémenter save/loading, undo/redo. J'ai une toile, peut dessiner dessus ainsi que 2 boutons que j'utilise pour sélectionner l'outil. Pour gérer le chemin j'ai créé un autre objet qui peut contenir un NSBezierPath, des valeurs de couleur et une valeur de taille pour chaque objet dessiné. C'est ce que je veux stocker dans le tableau. J'utilise mouseDown/Dragged/Up pour obtenir les coordonnées du tracé. Cependant, c'est là que les choses vont de travers. Je peux instancier l'objet supposé contenir le chemin/couleur/etc. info, mais lorsque j'essaie de changer une variable d'instance, l'application se bloque sans message utile dans le débogueur. Je vais essayer de garder mes extraits de code courts mais dites-moi si j'ai besoin d'en inclure d'autres. Le code a aussi dégénéré un peu de moi en essayant tant de choses pour le faire fonctionner.Y a-t-il quelque chose qui ne va pas avec mon Object Scope?
projet: Document de cacao application basée
Je les fichiers .m/.h suivants
MyDocument:NSDocument
- générée par XCodeDrawnObject:NSObject
- traite le chemin objet dessiné à-dire, la couleur, le type (ovale/rect) et la tailleCanvas:NSView
- bien, montre le dessin, traite avec la souris et boutons
Canvas est également responsable du maintien d'objets NSMutableArray
de DrawnObject
.
DrawnObject.h
ressemble à ceci:
#import <Foundation/Foundation.h>
//The drawn object must know what tool it was created with etc as this needs to be used for generating the drawing
@interface DrawnObject : NSObject {
NSBezierPath * aPath;
NSNumber * toolType;//0 for oval, 1 for rectangular etc....
float toolSize;
struct myCol{
float rd;
float grn;
float blu;
float alp;
} toolColor;
}
-(void)setAPath:(NSBezierPath *) path;
-(NSBezierPath *)aPath;
@property (readwrite,assign) NSNumber * toolType;
-(float)toolSize;
-(void)setToolSize:(float) size;
-(struct myCol *)toolColor;
-(void)setCurrentColor:(float)ref:(float)green:(float)blue:(float)alpha;
@end
Canvas.h
ressemble à ceci
#import #import "drawnObject.h" @interface Canvas : NSView { NSMutableArray * myDrawing; NSPoint downPoint; NSPoint currentPoint; NSBezierPath * viewPath;//to show the path as the user drags the mouse NSNumber * currentToolType; BOOL mouseUpFlag;//trying a diff way to make it work BOOL mouseDrag; } -(IBAction)useOval:(id)sender; -(IBAction)useRect:(id)sender; -(IBAction)showTool:(id)sender; -(NSRect)currentRect; -(NSBezierPath *)createPath:(NSRect) aRect; -(void)setCurrentToolType:(NSNumber *) t; -(NSNumber *)currentToolType; @end
Dans le fichier Canvas.m
il y a plusieurs fonctions pour faire face à la souris et NSView/XCode également abandonné dans
et
-(id)initWithFrame:(NSRect)frame-(void)drawRect:(NSRect)rect
Au départ, j'utiliser mouseUp
pour essayer d'insérer le nouveau DrawnObject
dans le tableau, mais cela a causé un plantage. Donc, maintenant j'utilise deux drapeaux BOOL
pour voir quand la souris a été libérée (maladroit mais j'essaye ....) dans drawRect
pour insérer dans le tableau. J'ai inclus la méthode ci-dessous et indiqué où elle provoque l'échec de l'application:
- (void)drawRect:(NSRect)rect { //This is called automatically // Drawing code here. //NSLog(@"Within drawRect tool type is %d", [self currentTool]); NSRect bounds = [self bounds]; NSRect aRect = [self currentRect]; viewPath = [self createPath:aRect]; //the createPath method uses the tool type to switch between oval and rect bezier curves if(mouseUpFlag==YES && mouseDrag==YES){ mouseDrag=NO; //Create a new drawnObject here DrawnObject * anObject = [[DrawnObject alloc]init];//- WORKS FINE UP TO HERE NSLog(@"CREATED NEW drawnObject"); [anObject setAPath:viewPath]; //- INSTANT APP DEATH!!!! NSLog(@"Set a path in drawnObject"); [anObject setToolType:[[NSNumber alloc]initWithInt:5]]; NSLog(@"Set toolType in DrawnObject"); [anObject setToolType:currentToolType]; [myDrawing addObject:anObject]; NSLog(@"Added Object"); } [[NSColor colorWithCalibratedRed:0.0 green:0.9 blue:0.0 alpha:0.5]set]; [NSBezierPath fillRect:bounds]; [[NSColor lightGrayColor]set]; [viewPath stroke]; //This is so the user can see where the drawing is being done //Now, draw the paths in the array [[NSColor blueColor]set]; for(DrawnObject * indexedObject in myDrawing){ [[indexedObject aPath] stroke];//This will do the actual drawing of ALL objects } }
Je suppose que cela a quelque chose à voir avec la portée de l'objet ou quelque chose, mais je ne peux pas le comprendre. Comme je l'ai dit, comme j'ai essayé des choses le code a subi une sorte de métamorphose, malheureusement pas pour le mieux. Comme ces BOOLS etc.
AIDE! Toute personne intelligente là-bas, dirigez-moi dans la bonne direction s'il vous plaît!
AJOUTE LA ON:
-(NSBezierPath *)createPath:(NSRect) aRect
{
NSBezierPath * tempPath;
//I need to know what tool
switch(0){ //temporary - this would use the toolType as a selector
case 0:
tempPath = [NSBezierPath bezierPathWithOvalInRect:aRect];
break;
case 1:
tempPath = [NSBezierPath bezierPathWithRect:aRect];
break;
default:
tempPath = [NSBezierPath bezierPathWithOvalInRect:aRect];
break;
}
return tempPath;
}
Nous devons voir l'implémentation de setAPath à partir de DrawnObject.m. –
- (void) setAPath: chemin (NSBezierPath *) { \t NSLog (@ "Chemin d'accès enregistré"); \t aPath = chemin; } –
Je suppose que je devrais faire le bit release/retain mais le fait est qu'il ne parvient jamais au NSLog dans la méthode. –