Question

I have created a subclass called Lines, that inherits from C4Shape. For now, all it does is create a random line when a class method is called.

The intention is that every new line begins at the previous line's pointB (i.e. end point) in order to make a continuing tree of lines. Eventually, I'll have multiple lines spawn from the same end point, old ones disappear, etc. Here's the code I have so far:

+(Lines *)createLineFromPoint:(CGPoint)startPoint {
CGPoint endPoint = CGPointMake([C4Math randomIntBetweenA:(startPoint.x-50) andB:(startPoint.x+50)],
                               [C4Math randomIntBetweenA:(startPoint.y-50) andB:(startPoint.y+50)]);
CGPoint linePoints[2] = {startPoint, endPoint};
Lines *newLine = [Lines new];
[newLine line:linePoints]; //This should make newLine a line type, should it not?
newLine.lineWidth = 3.0f;

return newLine;
}

-(void) setup {
[self performSelector:@selector(continueMakingLinesWithLine) withObject:(self) afterDelay:(3.0)];
}

-(void) continueMakingLinesWithLine {
[self.arrayOfLines addObject:[Lines createLineFromPoint:self.pointB]];
}

As far as I can tell, it should loop after the first call to continueMakingLinesWithLine in the C4WorkSpace; the first call is instantiated with a randomly generated CGPoint.

However, I am having a really hard time properly accessing the pointB property that was set during the last call to the method.

I received an error that tells me that it is because the C4Shape*(the Lines*) is not of type lines or arc.

However, the instance method should be making it of that type, shouldn't it?

Was it helpful?

Solution

I'm not sure what your actual error means. Your logic is quite correct though.

First things first, in your code you have the following:

[newLine line:linePoints]; //This should make newLine a line type, should it not?

The answer is YES, and it IS!

I copied your code into a new project and added each line to the canvas as it was created. The ran, albeit not the way I expected. However, that's not your fault.

You actually uncovered a small bug in the implementation of the [shapeObj line:...] method.

I will fix the bug in the C4iOS project on GitHub, however this won't appear in your project with the current installer you have.

Workaround

You can do one of two things:

1) Return C4Shape from your lines subclass and initialize it using [C4Shape line:linePoints]

2) Add the following to line 400 of C4Shape.m:

if(CGRectEqualToRect(CGRectZero, self.frame)) { self.frame = lineRect; }

For 1) your method should look like:

+(Lines *)createLineFromPoint:(CGPoint)startPoint {
    CGPoint endPoint = CGPointMake([C4Math randomIntBetweenA:.. andB:..],
                                   [C4Math randomIntBetweenA:.. andB:..]);
    CGPoint linePoints[2] = {startPoint, endPoint};
    C4Shape *newLine = [C4Shape line:linePoints];
    newLine.lineWidth = 3.0f;
    return (Lines *)newLine;
}

For 2) the end of the method in C4Shape.m should look like:

-(void)_line:(NSArray *)pointArray {
    //Default implementation
    //..
    //..
    newBounds.origin = CGPointZero;
    if(CGRectEqualToRect(CGRectZero, self.frame)) { self.frame = lineRect; }
    CGPathRelease(newPath);
    _initialized = YES;
}

If you do 2) you don't need to fix your current +(Lines *) method.

Other Things

I tightened up the code you posted above to look like the following:

@interface C4WorkSpace ()
@property NSMutableArray *arrayOfLines;
@end

@implementation C4WorkSpace

-(void) setup {
    self.arrayOfLines = [@[] mutableCopy];
    Lines *newLine = [Lines createLineFromPoint:self.canvas.center];
    [self.arrayOfLines addObject:newLine];
    [self.canvas addShape:newLine];
    [self continueMakingLinesWithLine];
}

-(void) continueMakingLinesWithLine {
    CGPoint p = ((Lines *)[self.arrayOfLines lastObject]).pointB;
    Lines *newLine = [Lines createLineFromPoint:p];
    [self.arrayOfLines addObject:newLine];
    [self.canvas addShape:newLine];
    [self runMethod:@"continueMakingLinesWithLine" afterDelay:1.0f];
}
@end

In setup I create the first line and add it to the canvas AND the array. Then, I let the continueMakingLinesWithLine method find the previous line, build a new one and then call itself again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top