Pregunta

I'm trying to write a new class inside a C4-Libpd project. All I want to do is, aslong I want tot learn how to manage classes in Objective-C, getting the functionality from the "sequencial" code I've written into some more Object Oriented way. One of the troubles I'm having is on how to "addShape" to the canvas as a method of the new class:

- (void) displayCrosshair{

    [self.canvas addShape:xLine];
    [self.canvas addShape:yLine];
    [self.canvas addShape:s];

}

gaves me an error:

Property canvas not found on object of type...

I understand that self.canvas from inside the class it's not correct as long as I haven't create another canvas inside the class as long as I want to add the Shape on the main canvas and just using the method in the way of working with objects. So, which is the correct way to do so?

¿Fue útil?

Solución

One of the easiest ways of getting things to happen on the canvas when a method or action occurs in a separate object is to use notifications. Using notifications does 2 things, it allows other objects to react to events in their own way, and it allows for decoupling (i.e. not hard-coding) references to objects.

You can post notifications like this:

@interface MyClass : C4Shape
-(void)displayCrosshair;
@end

@implementation MyClass
-(void)displayCrosshair {
    [self postNotification:@"displayCrosshairNotification"];
}
@end

Then, to get the canvas to listen for the notification you can do this:

-(void)setup {
    C4Shape *crossHair = ...;
    crossHair.hidden = YES;
    [self.canvas addShape:crossHair];
    [self listenFor:@"displayCrosshairNotification" fromObject:obj andRunMethod:@"displayCrosshair"];
}

-(void)displayCrosshair {
    crossHair.hidden = NO;
}

Alternatively, you can set up a property in your subclass for the canvas:

@interface MyClass : C4Shape
@property (readwrite, nonatomic) C4View *canvas;
@end

...and then make the hard reference to your canvas when you build your subclass in the C4WorkSpace.m like so:

@implementation C4WorkSpace {
    MyClass *obj;
}

-(void)setup {
    obj = [[MyClass alloc] init];
    obj.canvas = self.canvas;
    [self.canvas addSubview:obj];
}

This trick should work, but I prefer the notification method.


A final thought... If the subclassed object you're talking about actually IS the crosshair then I wouldn't even bother with the notification to the canvas.

Instead, I would create the crosshair as a subclass of C4Shape and have it manage its own visibility:

On the canvas:

-(void)setup {
    MyShape *crossHair = [[MyShape alloc] initWithFrame:...];
    [self.canvas addShape:crosshair];
}

In your shape subclass:

@interface MyShape : C4Shape
-(void)displayCrosshair;
-(void)hideCrosshair;
@end

@implementation MyShape
-(void)setup {
    [self addShape:xLine];
    [self addShape:yLine];
    [self hideCrosshair];
}

-(void)displayCrosshair {
    self.hidden = NO;
}

-(void)hideCrosshair {
    self.hidden = YES;
}
@end

Which is probably the best approach.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top