CorePlot display callout when select point is upside down - iphone

I have implemented the following code in my CPTScatterPlotDelegate to display a callout bubble:
-(void)scatterPlot:(CPTScatterPlot *)plot plotSymbolWasSelectedAtRecordIndex:(NSUInteger)index
{
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)plot.plotSpace;
CPTGraph *graph = plot.graph;
int yIdent = ((NSString*)plot.identifier).intValue;
NSNumber *yVal = [[_dataRange yForIndex:index] objectAtIndex:yIdent-1];
NSNumber *xVal = [_dataRange xForIndex:index];
double doublePrecisionPlotPoint[2];//[x,y]
doublePrecisionPlotPoint[0] = xVal.doubleValue;
doublePrecisionPlotPoint[1] = yVal.doubleValue;
CGPoint touchedPoint = [graph.defaultPlotSpace plotAreaViewPointForDoublePrecisionPlotPoint:doublePrecisionPlotPoint];
if(_annotation)
[_annotation dismissCalloutAnimated:YES];
_annotation = [[SMCalloutView alloc] init];
//todo appropriate units
_annotation.title = [NSString stringWithFormat:#"%.2f kg", yVal.doubleValue];
[_annotation presentCalloutFromRect:CGRectMake(touchedPoint.x, touchedPoint.y, 1, 1) inView:_view constrainedToView:_view permittedArrowDirections:SMCalloutArrowDirectionAny animated:YES];
}
_dataRange is just a custom class holding my data and _annotation is the instance of my callout.
The problem is I cant't get the position of the callout working properly. If I set _view to the ViewController.view I get the right callout but in the wrong place like this:
If I set _view to the CPTGraphHostingView instead I get the right point but the callout appears to be flipped like this:
How to I get the right plot point co-ordinates to display the callout?

You shouldn't add any subviews to the hosting view—it uses a flip transform on iOS so Core Plot can share drawing code between iOS and the Mac.
Use the -convertPoint:toView: or -convertPoint:fromView: method to convert touchedPoint from the hosting view's coordinate system to the ViewController.view coordinate system.

I have subclassed CPTGraphHostingView for a few charts so as an alternative I found any subview you add to it you should do the following:
subview.transform = CGAffineTransform(1.0, -1.0)
This doesn't change the fact that the coordinate system is (0,0)-bottom-left but the UIView you add will draw the right way up when rendered. Still use Eric's Answer for translating between coordinate systems but for anyone that finds themselves here trying to add a subview to CPTGraphHostingView I hope this helps.

Related

How to create a border around circle which is created using drawrect method in iphone

Hi in one of my application i had created a circle using drawrect method on UIView object.Now my concern i want draw a highlight border around the circle for that actually i used
myView.layer.borderWidth =3.0;
myView.layer.borderColor=[UIColor colorWithRed:myView.patternRed green:myView.patternGreen blue:myView.patternBlue alpha:1.0].CGColor;
But due to this code what is happening is a border is creating around the view and it's looks a rectangle, but i want to create a border around the circle itself. So if anyone know how to implement this functionality please let me know. Thanks in advance.
Try this
myView.layer.cornerRadius = 80.0f;
It'll curve your view into a circle.
Thanks.
you have to set some radius for the corners of that view so add this line
myView.layer.cornerRadius=20;
play with the numeric value to match your requirements
I hope it helps
This Works for me:
UIView *myView =[[UIView alloc]initWithFrame:CGRectMake(0,0,100,100)];
[self createRoundUIView:myView:80];
-(void)createRoundUIView:(UIView *)inputView sizeDiameter:(float)diameterSize;
{
CGPoint saveCenter = inputView.center;
CGRect frame = CGRectMake(inputView.frame.origin.x, inputView.frame.origin.y, diameterSize, diameterSize);
roundedView.frame = frame;
roundedView.layer.cornerRadius = diameterSize / 2.0;
roundedView.center = saveCenter;
}

UIImageView is floating around on screen after switching view

I'm trying to make a compass.
Basically I use an image of a compass needle as the directions-thing for the compass. It's animating fine around the center of the compass UNTIL I switch view, or add another view (ex. UIActionView or switch to another view controller):
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
float oldRadian = (-manager.heading.trueHeading *M_PI /180.0f);
float newRadian = (-newHeading.trueHeading *M_PI /180.0f);
CABasicAnimation *animation;
animation=[CABasicAnimation animationWithKeyPath:#"transform.rotation"];
animation.fromValue = [NSNumber numberWithFloat:oldRadian];
animation.toValue = [NSNumber numberWithFloat:newRadian];
animation.duration = 0.5f;
[compassArrow.layer addAnimation:animation forKey:#"animateMyRotation"];
compassArrow.transform = CGAffineTransformMakeRotation(newRadian);
}
After this I'm switching to another view controller that is the compassArrow imageview that was animating & started floating around.
Any ideas why this happens??
Set Compass arrow center as your Compass center
compassArrow.center = CompassImage.center;
Hope this Helps you
For the compassArrow imageView set the anchor point. so that it will rotate according to the anchor point.
use compassArrow.layer.anchorPoint = CGPointMake(0.5, 0.5);
hope i will help you.....
Get your image view frame first. For that you can type NSLog(#"%f %f %f %f", compassArrow.frame.origin.x,compassArrow.frame.origin.y,compassArrow.frame.size.width,compassArrow.frame.size.height); in viewDidLoad.
Note down the frame. Then in viewWillAppear method, add the line.
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];
[compassArrow setFrame:CGRectMake(CMPASSARROWFRAME.x, CMPASSARROWFRAME.y, CMPASSARROWFRAME.width, CMPASSARROWFRAME.height)];
}
Note this 'CMPASSARROWFRAME' is the frame of your compassArrow frame.
please check the frame before and after the switch and see whether they are same.If they are not same then it means that you are setting its frame wrongly somewhere .If the frame is the same before and after switching view then the problem is with layer transformation.Somewhere or the other you might have changed the anchor point or the layer location.
find out where it gets updated,use break points,follow the control flow and track the place where frame gets updates.You can find the step into button above the debug console in xcode.
I solved it using the removeFromSuperlayer-method before I change view. Problem was that I created multiple animations for the same key (#"animateMyRotation").
[compassArrow.layer removeFromSuperlayer];

uiimage not being put into subview correctly

This is a difficult problem to explain... but i'll do my best.
First a background on the problem, basically i am creating a paint like app for ios and wanted to add a functionality that allows the user to select part of the image (multi-touch shows an opaque rectangle) and delete/copy-paste/rotate that part. I have got the delete and copy-paste working perfectly but the rotation is another story. To rotate the part of the image I first start by copying the part of the image and setting it to be the background of the selected rectangle layer, then the user rotates by an arbitrary angle using a slider. The problem is that sometimes the image ends up being displayed from another location of the rectangle (meaning the copied image hangs off the wrong corner of the rectangle). I thought this could be a problem with my rectangle.frame.origin but the value for that seems to be correct through various tests. It also seems to change depending on the direction that the drag goes in...
These Are Screens of the problem
In each of the above cases the mismatched part of the image should be inside the grey rectangle, i am at a loss as to what the problem is.
bg = [[UIImageView alloc] initWithImage:[self crop:rectangle.frame:drawImage.image]];
[rectangle addSubview:bg];
drawImage is the users drawing, and rectangle is the selected grey area.
crop is a method which returns a part of a given image from a give rect.
I am also having trouble with pasting an arbitrarily rotated image.. any ideas on how to do that?
Edit: adding more code.
-(void)drawRect:(int)x1:(int)y1:(int)x2:(int)y2{
[rectangle removeFromSuperview];
rectangle = [[UIView alloc] initWithFrame:CGRectMake(x1, y1, x2-x1, y2-y1)];
rectangle.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:0.6];
selectionImage = drawImage.image;
drawImage.image = selectionImage;
[drawImage addSubview:rectangle];
rectangleVisible = true;
rectangle.transform = transformation;
Could it have anything to do with how i draw my rectangle? (above) I call this method from a part of a touchesMoved method (below) which may cause the problem (touch 1 being in the wrong location may cause width to be negative?) if so, is there an easy way to remedy this?
if([[event allTouches] count] == 2 && !drawImage.hidden){
NSSet *allTouches = [event allTouches];
UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];
UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];
[self drawRect:[touch1 locationInView:drawImage].x :[touch1 locationInView:drawImage].y:
[touch2 locationInView:drawImage].x :[touch2 locationInView:drawImage].y];
}
I'm not sure if this is your problem, but it looks like you are just assuming that touch1 represents the upper left touch. I would start out by standardizing the rectangle.
// Standardizing the rectangle before making it the frame.
CGRect frame = CGRectStandardize(CGRectMake(x1, y1, x2-x1, y2-y1));
rectangle = [[UIView alloc] initWithFrame:frame];

Way to draw NSString on a curved path? [duplicate]

Is there a set of string attributes I can specify that will draw the text at an angle when I call:
[label drawAtPoint:textStart withAttributes:attributes];
Here's an example that uses a transform to rotate the drawing context. Essentially it's just like setting a color or shadow, just make sure to use -concat instead of -set.
CGFloat rotateDeg = 4.0f;
NSAffineTransform *rotate = [[NSAffineTransform alloc] init];
[rotate rotateByDegrees:rotateDeg];
[rotate concat];
// Lock focus if needed and draw strings, images here.
[rotate release];
NSString itself doesn't have rotation, but you can rotate the context. The string will always be drawn "horizontally" as far as the coordinate space goes, but what actual direction that corresponds to depends on the context. Just use NSAffineTransform to spin it as needed.

iPhone Programming setNeedsDisplay not working

Implemented my own drawRect method and I'm trying to redraw the shape from a Controller class and I can't figure out how to correctly implement setNeedsDisplay to redraw the UIView. Please help!!
I know the code is ugly, but here is the custom method:
- (void)drawRect:(CGRect)rect{
// Drawing code
NSArray *kyle = [self pointsForPolygonInRect:rect numberOfSides:[pshape numberOfSides]];
CGContextRef c = UIGraphicsGetCurrentContext();
int counter = [kyle count];
NSLog(#"counter: %d",counter);
int i = 0;
BOOL first = YES;
NSValue *kylevalue;
CGPoint thePoint;
for (i = 0; i < counter; i++) {
kylevalue = [kyle objectAtIndex:i];
thePoint = [kylevalue CGPointValue];
if (first) { //start.
CGContextMoveToPoint(c, thePoint.x, thePoint.y+5.0);
first = NO;
} else { //do the rest
CGContextAddLineToPoint(c, thePoint.x, thePoint.y+5.0);
}
}
CGContextClosePath(c); //solid color
CGContextDrawPath(c, kCGPathFillStroke);
}
I've had similar problems with redrawing not working as I expected either. It seems as though setNeedsDisplay does not force children to redraw, for those you need to call their setNeedsDisplay method.
For my needs I wrote a category to redraw the entire screen by calling setNeedsDisplay on every single view. This can of course easily be modified to start from a specific view as opposed to all windows.
#implementation UIApplication (Extensions)
+ (void) redrawScreen {
NSMutableSet* todo = [NSMutableSet set];
NSMutableSet* done = [NSMutableSet set];
[todo addObjectsFromArray:[[UIApplication sharedApplication] windows]];
while ([todo count] > 0) {
UIView* view = [todo anyObject];
[view setNeedsDisplay];
[done addObject:view];
[todo removeObject:view];
if (view.subviews) {
NSMutableSet* subviews = [NSMutableSet setWithArray:view.subviews];
[subviews minusSet:done];
[todo unionSet:subviews];
}
}
}
#end
Hope this is of help to someone
I'm not sure I understand your question. Calling -setNeedsDisplay on a view causes it to be redrawn via its -drawRect: method.
just a few thoughts
1. have you verified that your method is getting called?
2. have you verified that your array of points is in fact populated with more than one point?
3. are the points actually in the viewable area of the frame?
4. I don't see you setting the stroke line width, color or fill colors.
Sometimes reason can be very simple: File's owner has no connection to UIView object. i.e. it's Outlet is not setup properly.
Use IB, ctrl button and drag method :)
If your plot has the drawRect method, look at your viewController, at the code where it connects to your plot. Is that hooked up properly? Is the little circle by the property hollow? or filled in. That little circle must be filled in if the property is connected properly. If it is hollow, bring up the story board.
Find the plot object in the story board. Control drag from the plot object in the story board over to the empty circle on the view controller. Now you've hooked up the outlet. Try running it again, and see if your drawRect is called now.