How to add dragging option to SKAnnotaion? - ios

I have a feature to place an annotation to a map by performing a long press at a point on the map. Then user can move the annotation to other position by dragging.
I was able to achieve that using RouteMe, but now I want to replace RouteMe with Skobbler.
Is there any property to enable dragging for annotations/markers on map using Skobbler? If yes, please help me achieve it.

Don't you wan't to do this :
Setting the annotation delegate, then
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
coordinate = newCoordinate;
if (self.delegate respondsToSelector:#selector(mapAnnotationCoordinateHaveChanged))
[self.delegate performSelector(#selector(mapAnnotationCoordinateHaveChanged))];
}
In your delegate :
- (void) mapAnnotationCoordinateHaveChanged{
//some coordinates update code
}

Related

How to know if blue dot is within visible portions of my mapView?

I am working with MKMapView. When the user scrolls the map in a way that blue dot indicating user's current location disappears from his sight, tapping a button on mapView brings him back to the portion that contains that blue dot. I am doing it simply by setting
self.mapView.centerCoordinate = self.mapView.userLocation.coordinate;
on button's action method.
But I have to change button's image once he scrolls away from blue dot. So, how would I know if blue dot is not in the portions of the map that is currently visible to the user.
You can add a delegate to the map view, mapView:regionDidChangeAnimated:, so that you are informed when a scroll event has occurred.
In your implementation of that method you can get the visibleMapRect and use MKCoordinateRegionForMapRect to get the associated real world coordinates of the map view. You can then determine if the current user location is visible (this requires a simple calculation, I don't think there's a built in method).
You can use the built in boolean flag self.mapView.userLocationVisible
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
//do something here
if(self.mapView.userLocationVisible){
//Blue dot visible
}
else{
//Blue dot hidden
}
//do something here
}
For those interested in code:
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
if (MKMapRectContainsPoint(self.mapView.visibleMapRect, MKMapPointForCoordinate(self.mapView.userLocation.coordinate))) {
NSLog(#"blue dot visible");
}else{
NSLog(#"blue dot not visible");
}
}

Google Maps SDK iOS - prevent map from changing location on zoom

I have a problem that I can't solve for some time.
I have a GMSMapView with imageView in front of it in the center. In result - I can drag map and always have centered pin. But problems come when I zoom the map.
On zooming - position of map target changes and my imageView points to another location.
I can detect if zoom changed, but I cant actually force GMSMapView to do ONLY zoom without any location changing.
-(void) mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position
{
if (mZoomLevel != mapView.camera.zoom)
{
mZoomLevel = mapView.camera.zoom;
}
}
So basically, I want to have always centered pin, even if I perform zoom.
I tried GMSMarker - but it has problems with performance when following map center. It doesn't do it instantly, so I decided to use imageView.
Main question: how to lock current location of the map while performing zoom?
Google fixed this issue with google maps sdk 1.10.0.
The solution is to simply add this line when configuring GMSMapview:
_mapView.settings.allowScrollGesturesDuringRotateOrZoom = NO;
Well, after 10 days of going back to this problem, I finally solved it!
The answer was pretty easy!
Few steps here:
1. Add imageView as marker on top of the GMSMapView
2. Add UIPanGestureRecognizer to the GMSMapView (don't forget to set delegate, it is important)
3. Then use this code:
- (void) didPan:(UIPanGestureRecognizer*) gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
{
_mapView.settings.scrollGestures = true;
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer.numberOfTouches > 1)
{
_mapView.settings.scrollGestures = false;
}
else
{
_mapView.settings.scrollGestures = true;
}
return true;
}
Swift 3:
mapView.settings.scrollGestures = false

Google Maps SDK, iOS, how to calculate difference in camera movement

I am using Google maps for iOS. Everytime the user pans left or right I reload some data based on new position using this method
- (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position {
Now I am trying to find a way to calculate that if the user moved a little bit in the same view, and the change was not drastic and it does not warrant another data load, then do not load it. To that End I created a variable called mostRecentCoord that I maintain on load that holds initial location
- (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position
{
//Here mostRecentCoord is self descriptive, latest entry before this move occured.
if(position.target.latitude == mostRecentCoord.latitude && position.target.longitude ==
mostRecentCoord.longitude) {
return;
}
I thought that I can put a limit on the change in lngtitude or latitude , and based on that decide whether to load new data or not, but then I have to take into account zoom level, scope of coverage.
Anyone has ideas on this? would appreciate it
Here's one idea:
When you do your data fetch, pad the bounds of the visible region on all sides by some amount (eg by 20%).
Then when the view moves, if the new visible region is wholly contained inside your padded region, you don't need to reload the data. If some of the new region is outside, you need to reload.
idleAtCameraPosition is called at every time the camera has ended it's view changes.
lat, and lng is your movement until the user stops to pan (..changing the camera). You can convert that to pixels and vice versa using: CGPoint point = [map.projection pointForCoordinate:coordinates];
GMSCameraPosition *lastCameraPosition;
- (void)mapView:(GMSMapView *)pMapView didChangeCameraPosition:(GMSCameraPosition *)position {
if (lastCameraPosition == nil) lastCameraPosition = position;
// Algebra :) substract coordinates with the difference of camera changes
double lat = position.target.latitude - lastCameraPosition.target.latitude;
double lng = position.target.longitude - lastCameraPosition.target.longitude;
}
dont forget to:
- (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position {
lastCameraPosition = nil;
}

Getting the touch feedback on CPTXYGraph Pie Chart

I am drawing a pie chart using the CPTXYGraph in Core Plot. I have used the delegate method
-(void)pieChart:(CPTPieChart *)plot sliceWasSelectedAtRecordIndex:(NSUInteger)index
to perform some actions when a particular slice of a pie is clicked. But when I touch the piechart I need to have a feedback or some type of image change to be shown to signify that particular slice is touched just like the button events.
Are there any delegate methods to achieve the same.
There'll be some work to do.
First of all, Implement this into Pie chart delegate function.
-(void)pieChart:(CPTPieChart *)plot sliceWasSelectedAtRecordIndex:(NSUInteger)index
{
indexOfPieGraphPlot = index; //gives index of pie which is selected.
isPieGraphPlot = YES; //boolean. if set to yes, will call rootcontroller function which will add pop up.
}
Then add the CPTPlotSpaceDelegate in .h file
then use this function
- (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceUpEvent:(id)event atPoint:(CGPoint)point
{
if(isPieGraphPlot) //if yes call showpopup of rootcontroller
{
isPieGraphPlot = NO;
[rootController showPopUpView:point indexForPlot:indexOfPieGraphPlot];
// point gives the x,y of the pie over which you want a pop up.
}
else // if no then call remove popup from rootcontroller. this, incase user clicks anywhere else in graph.
{
[rootController removePopUp];
}
return YES;
}
Implement the -sliceFillForPieChart:recordIndex: method in your datasource. Keep track of the selected slice (if any) and use that to decide what fill to apply to each slice. Call -reloadData on the plot any time the selection changes to force it to load new slice fills.

Map View always center map on my location

I use the following code to get my location when a user presses a button
[mapview setShowsUserLocation:YES];
and then the follwoing to center the map to te user's location
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
[mapView setCenterCoordinate:mapView.userLocation.location.coordinate animated:YES];
}
My question is how to prevent the map from always centering on my location? I want to allow the user to pan the map.
Center on the location only the first time you show the map. Here is some pseudo code...
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
if(shouldCenterLocation){
[mapView setCenterCoordinate:mapView.userLocation.location.coordinate animated:YES];
shouldCenterLocation = FALSE;
}
//do all your other stuff here
}
shouldCenterLocation is a boolean flag that you can set to TRUE the first time the map is shown, then set it to FALSE until you exit the view (or any other condition you have for showing the center location).
edit: you can toggle the state of shouldCenterLocation in the same method that you handle the button press.
I think it came in with iOS5, you can now drop the delegate stuff and just set the userTrackingMode of the MKMapView. Set it to MKUserTrackingModeFollow to make the make move along with the user and then when they start panning the map around it'll turn off the tracking mode automatically, you then just need to provide a button to turn it back on.
On swift 3 I prefer use animated method:
mapView.setUserTrackingMode(.follow, animated: true)
but set property good worked:
mapView.userTrackingMode = .follow

Resources