I'm working with the C4 framework on a project and I'm having a bit of trouble with using the gesture controls and calling methods from C4WorkSpace.
I found this link that had to do with this problem but it didn't seem to stop my program from throwing an error.
A little background: I'm creating a custom button class that has 4 properties: UIColor, C4Shape and 2 floats (x/y position). I'm storing the custom button objects in an array and have this bit of code going to add a gesture to each button and add it to the canvas.
C4WorkSpace.m
for (button in buttonArray){
[button.shape addGesture:TAP name:@"tapGesture" action:@"tapped"];
[self.canvas addShape:button.shape];
[self listenFor:@"tapped" fromObject:button andRunMethod:@"doThis:"];
}
And I also have a function outside my '-(void)setup' that just prints a log message:
-(void)doThis:(NSNotification *)notification{
NSLog(@"notification test");
}
I have extended my C4Shape class with a category and when I call this method it works fine:
#import "C4Shape+myC4Shape.h"
@implementation C4Shape (myC4Shape)
-(void)printTest{
NSLog(@"this is a print test");
}
@end
The error I'm getting gets thrown when I try and tap on a button, it says: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[C4Shape tapped]: unrecognized selector sent to instance 0x931e9c0'
I have my "action" set to 'tapped', but that's just something I made up. I know this usually calls a method inside the shape class, but I'm trying to call a method that isn't in the C4Shape class but on the main WorkSpace. I'm not sure what's causing this or what I'm doing wrong? Is there something specific I need to be writing in the 'action' part of the method?
this Obj-C stuff can be confusing at first. Hopefully this will help.
I notice two things for you to change.
The first is in regards to your TAP
gesture. When you add this to your code you're actually telling the gesture to recognize a TAP and then run the tapped
method. However, this method doesn't exist (hence the -[C4Shape tapped]: unrecognized selector sent to instance 0x931e9c0
). You should have a method in your code called -(void)tapped{};
for this message to go away.
The following code illustrates this:
@implementation C4WorkSpace
-(void)setup {
[self addGesture:TAP name:@"tap" action:@"tapped"];
}
-(void)tapped {
C4Log(@"tapped!");
}
@end
Putting that into a shape is quite similar.
Second, for the subclassing, C4Shape (and all other visual objects) inherit from C4Control so I would suggest that subclassing C4Control isn't the best approach. For creating your own custom button with a C4Shape I would subclass C4Shape directly.
The above code would look exactly the same for a subclassed C4Shape except that if you created a MyShape subclass would have @implementation MyShape
instead.
Finally, you want to add a little broadcast message to your tap
method so that the canvas can listen for it... All in all your .h
and .m
files for your subclass should look like this:
.h
#import "C4Shape.h"
@interface MyShape : C4Shape
@end
.m
#import "MyShape.h"
@implementation MyShape
-(void)setup {
[self addGesture:TAP name:@"tap" action:@"tapped"];
}
-(void)tapped {
[self postNotification:@"tapNotification"];
}
@end
Finally, with those two files in your project you can add the following to your workspace:
#import "C4WorkSpace.h"
#import "MyShape.h"
@implementation C4WorkSpace
-(void)setup {
MyShape *m = [[MyShape alloc] init];
[m rect:CGRectMake(0, 0, 100, 100)];
m.center = self.canvas.center;
[self.canvas addShape:m];
[self listenFor:@"tapNotification" fromObject:m andRunMethod:@"heardTap:"];
}
-(void)heardTap:(NSNotification *)aNotification {
MyShape *notificationShape = (MyShape *)[aNotification object];
C4Log(@"%4.2f,%4.2f",notificationShape.center.x,notificationShape.center.y);
C4Log(@"%@",notificationShape.strokeColor);
}
@end
Here's a link to a gist with the 3 files you'll need for this to run.
Button Subclass with Canvas Listener
PS thanks for giving C4 a try!
Oh, and this is the output I get in Xcode's console when I tap on the square:
[C4Log] 384.00,512.00
[C4Log] UIDeviceRGBColorSpace 1 0.1 0.1 1
This gives me the x
and y
coordinates, as well as the strokeColor
of the "button" without having to add these as objects to the MyShape
class (because they already exist in C4Shape
).