2

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?

4
  • The error you're getting is being thrown because the button class doesn't have a "tapped" method declared in its .m file. Before I can post an answer I have a couple of questions for you: 1) What kind of subclass is your custom button class? 2) What exactly do you want to do with the color objects? Commented May 2, 2013 at 17:54
  • p.s. just asking those questions because there's a couple ways to answer your question Commented May 2, 2013 at 17:56
  • Thanks for getting back I figured that's why it was getting thrown, but I wasn't sure what to do about it exactly (sorry if that sounds vague) 1) My button class is inheriting from C4Control. Inside it is a C4Shape property called shape as well as a UIColor and x/y values as floats 2) Eventually I will have all these button objects added to the canvas and what we wanted was that when someone taps on a button it sends a UDP packet with the buttons UIColor as well as the IP associated with the iPad-this stuff I won't be doing This is my first time working in ObjC/C4 so im still a little lost Commented May 3, 2013 at 16:00
  • great thanks for the info. i'll put up an answer for you shortly. Commented May 3, 2013 at 16:15

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.