Domanda

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?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top