I am developing a pie chart application using Core-Plot on iPhone.
There are no issues in drawing the pie-chart. But I am unable to interact with its slices. I even tried interacting with them using touchesBegan event. But even this method is not getting invoked.
Please help me in this regards. User interaction has been enabled.
Try to implement <CPPiechartDelegate> in your class.
Then implement
-(void)pieChart:(CPPieChart *)plot sliceWasSelectedAtRecordIndex:(NSUInteger)index
{
// This will inform you the index of the slice that was touched or clicked.
}
Also use latest Coreplot framework as old framework has some issues related to selecting touch event.
Edit
Try This
In yourViewController.h file
#import <UIKit/UIKit.h>
#import "CorePlot-CocoaTouch.h"
#interface yourViewController : UIViewController <CPPieChartDataSource, CPPieChartDelegate>
{
}
In yourViewController.m file
-(void)pieChart:(CPPieChart *)plot sliceWasSelectedAtRecordIndex:(NSUInteger)index
{
NSString *selectedIndex = [NSString stringWithFormat:#"Selected index: %lu", index];
NSLog(#"You have selected index=%#",selectedIndex);
}
Finally view your gdb log to get the response ,which index you have selected.
Related
I have set up a sharedCache using ASIHttprequest and it is created from the xml I parse in my subview. I was woundering if I can then access that sharedCache from my mainview to do a few things things that will speed my tables up?
any idea, suggestions, thoughts of examples would be greatly appreciated.
There's already a sharedCache provided by ASIDownloadCache. It's visible anywhere in your application (assuming you #import "ASIDownloadCache.h"), so you should be able to call [ASIDownloadCache sharedCache] and use it.
EDIT: To use several caches is not too tricky. Create a separate class which is included by both your main view and your subview. In there, define a method to return one or more ASIDownloadCache objects, and provide an implementation, similar to this:
DownloadCaches.h
#import "ASIDownloadCache.h"
#interface DownloadCaches : NSObject
+ (ASIDownloadCache *)imageCache;
#end
DownloadCaches.m
#import "DownloadCaches.h"
#implementation DownloadCaches
static ASIDownloadCache *imageCache = nil;
+ (ASIDownloadCache *)imageCache
{
if(imageCache == nil)
{
imageCache = [[ASIDownloadCache alloc] init];
// set imageCache-specific options here
}
return imageCache;
}
#end
You only ever need to call [DownloadCaches imageCache] and it will be initialised if not already, and then returned to you.
I want to create a custom MKAnnotationView callout as shown in this image. I have tested several solutions but they only allow customization of the left/right images and title/subtitle. Can anybody please give me some source code or tutorial link for it?
Currently I am clueless. Please help.
I understand you want a pin with a custom callout.
We can't create a custom callout, but we can create an annotation with a completely customized view. So the trick is to add a second annotation when the first is selected, and make the 2nd annotation view look like a callout bubble.
This is the solution posted by users djibouti33 and jacob-jennings in the answer: MKAnnotationView - Lock custom annotation view to pin on location updates, which in turn is based in a blog post from Asynchrony Solutions. For explanation purposes, here is some UML from a forked project:
This is a big hack, but also the cleanest way I've seen to implement custom annotations.
Start with a NSObject "Content" class which has a coordinate, the class of the callout view to use (in the UML is AnnotationView, but you can create more and set them here), and a dictionary of random values with the title, photo url, etc. Use this class to initialize a MKAnnotation "Annotation" object.
#import <MapKit/MapKit.h>
#interface Content : NSObject
#property (nonatomic,assign) CLLocationCoordinate2D coordinate;
// ...
#interface Annotation : NSObject <MKAnnotation, AnnotationProtocol>
-(id) initWithContent:(Content*)content;
// ...
The Annotation implements AnnotationProtocol to announce it wants to handle the creation of its own MKAnnotationView. That is, your MKMapViewDelegate should have code like this:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// if this is a custom annotation, delegate the implementation of the view
if ([annotation conformsToProtocol:#protocol(AnnotationProtocol)]) {
return [((NSObject<AnnotationProtocol>*)annotation) annotationViewInMap:mapView];
} else {
// else, return a standard annotation view
// ...
}
}
The view returned will be of type AnnotationView, which implements AnnotationViewProtocol to announce that it wants to handle selection/deselection. Therefore, in your map view controller, the methods mapView:didSelectAnnotationView: and mapView:didDeselectAnnotationView: should delegate in a similar way to what we saw before.
When the annotation is selected, a second annotation (CalloutAnnotation) is added, which follows the same behaviour, but this time the view returned (CalloutView) is initialized from a XIB, and contains Core Graphics code (in BaseCalloutView) to animate and replicate a callout.
The initializer of the CalloutView class:
- (id)initWithAnnotation:(CalloutAnnotation*)annotation
{
NSString *identifier = NSStringFromClass([self class]);
self = [super initWithAnnotation:annotation reuseIdentifier:identifier];
if (self!=nil){
[[NSBundle mainBundle] loadNibNamed:identifier owner:self options:nil];
// prevent the tap and double tap from reaching views underneath
UITapGestureRecognizer *tapGestureRecognizer = ...
}
return self;
}
To be able to push another view controller from the callout view I used notifications.
The SO answer I linked at the top contains two complete projects implementing this code (class names may differ). I have another project using the UML above at https://github.com/j4n0/callout.
I added custom UIButton in MKAnnotationView. And on click of that button I have shown popOver with rootViewController with the view similar as you have shown above.
I know this question is from 2011 but for people who still find it in a search:
In iOS 9 you have MKAnnotationView.detailCalloutAccessoryView which entirely replaces the standard callout.
I am using the Core Plot framework to draw a pie chart, and am having no issues in drawing the pie chart itself.
However, I need the pie chart to be interactive in nature, i.e., if I tap on any particular section in the pie chart, it should trigger the navigation to a page showing details of that particular section.
I tried using the method -(void)pieChart:sliceWasSelectedAtRecordIndex:, but that delegate method was never called. What do I need to enable this touch interaction?
I have implemented pie piece selection in my iPad app with CorePlot 0.2.2. Your guess to use
(void)pieChart:sliceWasSelectedAtRecordIndex: is correct, but maybe you have forgotten
to declare the following two things:
Does your controller declares the CPPieChartDelegate protocol?
Did you tell the pie chart that your controller is its delegate?
My view controller looks like this in the header declaration:
#interface YourViewController : UIViewController < CPPieChartDataSource,
CPPieChartDelegate,
... >
{
...
CPXYGraph* pieGraph;
CPGraphHostingView* pieView;
}
#property (nonatomic, retain) IBOutlet CPGraphHostingView* pieView;
- (void)pieChart:(CPPieChart *)plot sliceWasSelectedAtRecordIndex:(NSUInteger)index;
#end
The creation of the pie chart is called during the (void)viewDidLoad, where I set the data source and the delegate of the pie chart:
-(void)viewDidLoad {
[self createPie];
}
-(void)createPie {
pieGraph = [[CPXYGraph alloc] initWithFrame:CGRectZero];
pieGraph.axisSet = nil;
self.pieView.hostedGraph = pieGraph;
CPPieChart *pieChart = [[CPPieChart alloc] init];
// This is important in order to have your slice selection handler called!
pieChart.delegate = self;
pieChart.dataSource = self;
pieChart.pieRadius = 80.0;
[pieGraph addPlot:pieChart];
[pieChart release];
}
- (void)pieChart:(CPPieChart *)plot sliceWasSelectedAtRecordIndex:(NSUInteger)index {
// Do whatever you need when the pie slice has been selected.
}
Using the last corePlot framework (1.4) i could not find CPPieChart but I fixed with CPTPieChartDelegate:
#interface CPDFirstViewController : UIViewController <CPTPlotDataSource, CPTPieChartDelegate, ...>
and this method:
-(void)pieChart:(CPTPieChart *)pieChart sliceWasSelectedAtRecordIndex:(NSUInteger)index
{
// Put your action here
}
CPPieChartDelegate is not recognized any more as Delegate from Xcode, using CorePlot 1.4
Hope it helps.
dom
I have gone through certain related answers but dont seem to get correct answer or the answer I need.
As we open googlemap in mkmap view I want to open openstreet map in mkmapview.
If there is any link or sample code showing it please pass it on.
Thanks in advance
MKMapView conforms to Google Map terms and conditions so it uses only google map. You cant integrate OpenStreetMap just like that into MKMapView. Google code has a API RouteME which renders OpenStreetMap in iphone.
RouteMe also provide a good documentation how to include into our project. So feel free to use that.
Import these Frameworks:
#import <MapKit/MapKit.h>
Include this delegate
#interface ViewController () <MKMapViewDelegate>
Add this code to your preexisting viewDidLoad method
(void)viewDidLoad
{
// Tile system URL template goes here
NSString *template = #"http://tile.openstreetmap.org/{z}/{x}/{y}.png";
// Associating overlay with URL template
MKTileOverlay *overlay = [[MKTileOverlay alloc] initWithURLTemplate:template];
// Allowing overlays on MKMapView & disabling Apple map data
overlay.canReplaceMapContent = YES;
// Adding overlay to MKMapView above Apple lables
[self.mapView addOverlay:overlay level:MKOverlayLevelAboveLabels];
// Linking the delegate to allow the next method to be called
self.mapView.delegate = self;
}
And this somewhere in your class that’s mapView’s delegate (most likely a view controller).
(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKTileOverlay class]]) {
// Overlay the tile with the new template
return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
}
return nil;
}
While working with the EventKit on iPhone I noticed that some events can exist which cannot be modified. Examples I encountered so far are birthdays and events synced with CalDAV. When you view the event's details in the standard built-in calendar app on iPhone the "Edit" button in the top-right corner is not visible in these cases, where it would be visible when viewing "normal" events.
I've searched everywhere, read all documentation there is but I simply can't find anything that tells me how to detect this behavior! I can only detect it afterwards:
edit an event's title
save it to the event store
check the event's title, if it has not changed it is not editable!
I am looking for a way that I can detect the non-editable behavior of an event beforehand. I know this is possible because I've seen other calendar apps implement this correctly.
Ok it appears as if the SDK doesn't provide me with anything I can use to check if an EKEvent is read-only. I created a workaround by creating a category that adds an "isReadOnly" method to all EKEvent instances.
EKEvent+ReadOnlyCheck.h
#interface EKEvent(ReadOnlyCheck)
- (BOOL) isReadOnly;
#end`
EKEvent+ReadOnlyCheck.m
#import "EKEvent+ReadOnlyCheck.h"
#implementation EKEvent(ReadOnlyCheck)
- (BOOL) isReadOnly {
BOOL readOnly;
NSString *originalTitle = [self.title retain];
NSString *someRandomTitle = [NSString stringWithFormat:#"%i", arc4random()];
self.title = someRandomTitle;
readOnly = [originalTitle isEqualToString:self.title];
self.title = originalTitle;
[originalTitle release];
return readOnly;
}
#end
When the above files are in place I can simply call isReadOnly on the EKEvent of my choice.
#import "EKEvent+ReadOnlyCheck.h"
...
if ([event isReadOnly]) {
// Do your thing
}
...
I haven't worked with Event Kit yet, but from the documentation it seems that editability is a property of a calendar, not of an event. event.calendar gets you the event's calendar, and calendar.allowsContentModifications tells you if the calendar is read-only or read-write.
try allowsEditing property of EKEventViewController before displaying the view.
Yes. It is possible. The code would look like following :
Try relating to code by logging the output of objects I use with editable/non editable events and you will understand the working:)
EKEventViewController *controller = [[EKEventViewController alloc] init];
controller.event = myEvent; /*myEvent is of type EKEvent*/
if(controller.navigationItem.leftBarButtonItem != NULL)
{
/*Event is Editable, Your code here*/
}
I think adding this category method for EKEvent handles all cases where events are not editable:
- (BOOL)isReadOnly {
if (self.calendar.allowsContentModifications == NO) return YES;
if (self.organizer && [self.organizer isCurrentUser] == NO) return YES;
return NO;
}