2

What I'm hoping to achieve is to call a method in C4Workspace.m by using:

[shape addGesture:SWIPELEFT name:@"swipeLeft" action:@"leftSwipeMethod"];

I know that this attempts to call a method called "leftSwipeMethod" within the C4Shape class, but in the documentation it also mentions you can call methods from the super class (which is what I think I'm trying to do?).

I checked other questions like this and I'm aware that you're not supposed to do this in normal objective-c... but I wonder if that is the case with C4 as well.

Is there any other way to get the same result or do I have to create a sub class?

Greg Debicki
  • 235
  • 2
  • 6
  • Depends... Are you wanting to trigger this from inside the shape? Or, from the workspace itself? – C4 - Travis Mar 08 '13 at 03:48
  • 1
    @C4-Travis I'm not quite sure how to phrase what i want. I want the method to run when I do a swipe gesture on the shape (not the canvas) – Greg Debicki Mar 08 '13 at 04:01
  • Ok, so you run the gesture on the shape, and then: A) trigger a method inside the shape? or B) trigger a method on the canvas? – C4 - Travis Mar 08 '13 at 04:41
  • 1
    @C4-Travis a method inside the shape. I want the shape to change color... but I want to run it from the workspace, as in shape.fillColor = C4RED; – Greg Debicki Mar 08 '13 at 22:24

1 Answers1

2

Okay, the easiest way to do this is to set up your canvas to listen for the right method that is being called inside the C4Shape (actually, it's from any C4Control so this technique will work for all visual objects.

  1. First, create a shape and add it to the canvas.
  2. Add a gesture to the shape, triggering the appropriate swipe method
  3. Tell the canvas to listen for a notification from the shape
  4. Do something (i.e. change the shape's color) when the canvas hears the notification

The following code sets up the shape:

@implementation C4WorkSpace {
    C4Shape *s;
}

-(void)setup {
    s = [C4Shape rect:CGRectMake(0, 0, 192, 96)];
    s.center = self.canvas.center;
    [s addGesture:SWIPELEFT name:@"leftSwipeGesture" action:@"swipedLeft"];
    [self.canvas addShape:s];

    [self listenFor:@"swipedLeft" fromObject:s andRunMethod:@"randomColor"];
}

-(void)randomColor {
    s.fillColor = [UIColor colorWithRed:[C4Math randomInt:100]/100.0f
                                  green:[C4Math randomInt:100]/100.0f
                                   blue:[C4Math randomInt:100]/100.0f
                                  alpha:1.0f];
}
@end

However, this is hard-coded... A nicer, more dynamic way of doing this is to listen from a lot of objects and have a randomColor: method that also accepts the notification so that you can pull out the shape that's doing the notifying.

@implementation C4WorkSpace {
    C4Shape *s1, *s2;
}

-(void)setup {
    s1 = [C4Shape rect:CGRectMake(0, 0, 192, 96)];
    [s1 addGesture:SWIPELEFT name:@"leftSwipeGesture" action:@"swipedLeft"];

    s2 = [C4Shape rect:CGRectMake(0, 0, 192, 96)];
    [s2 addGesture:SWIPELEFT name:@"left" action:@"swipedLeft"];

    s1.center = CGPointMake(self.canvas.center.x, self.canvas.center.y - s1.height * 1.25);
    s2.center = CGPointMake(self.canvas.center.x, self.canvas.center.y + s2.height * 0.25);

    NSArray *shapes = @[s1,s2];
    [self.canvas addObjects:shapes];

    [self listenFor:@"swipedLeft" fromObjects:shapes andRunMethod:@"randomColor:"];
}

-(void)randomColor:(NSNotification *)notification {
    C4Shape *shape = (C4Shape *)notification.object;
    shape.fillColor = [UIColor colorWithRed:[C4Math randomInt:100]/100.0f
                                      green:[C4Math randomInt:100]/100.0f
                                       blue:[C4Math randomInt:100]/100.0f
                                      alpha:1.0f];
}
@end

Things to note in the second example:

First, to accept a notification, the method being run has to have the format:

-(void)randomColor:(NSNotification *)notification {}

Second, to trigger this the method name you use in listenFor has to have a : like so:

@"randomColor:" 

Third, you grab the object that just received a swipe gesture by pulling it from the notification it sent:

C4Shape *shape = (C4Shape *)notification.object;
C4 - Travis
  • 4,502
  • 4
  • 31
  • 56
  • 1
    Ok, that's great. Thank you. What if I want a specific color for each swipe direction, is it possible to use just one method and somehow pass the direction of the swipe to that method (kind of like how you passed which object sent the notification)? I'm sort of imagining something like andRunMethod:@"changeColor:" withString:@"(the direction that it was swiped)" or something like that... or do I just have to write a separate method for each swipe direction? – Greg Debicki Mar 09 '13 at 01:03
  • You're on the right track. Generally, however when you're tracking gestures its best to contain the use of them within the object or object / controller pair. So, you want to do the tracking and handle the behaviour within the same object (essentially). For the technique you're talking about, if you want to handle it from the canvas and for simplicity you can just write separate methods for each... swipeLeftRandomColor: or something like that. There's not too much overhead in doing this. – C4 - Travis Mar 09 '13 at 06:51