MapView - change map center point - ios

I have this view with a map that covers most of the screen's area.
On top of the map, I have some images, buttons, text boxes. They're located in the top portion of the map, which I'm calling here "useless map", while the bottom part is for actually viewing the map. This is the "useful map".
By default, the map property centerCoordinate is the center with respect to the full map, as seen as the red circle in the image:
The useful map is marked in green, and I wanted the green circle to be used as a center point.
I can center the map or add a pin, for instance, in that precise point by adding or subtracting from the coordinate's latitude, but the actual value I need to add depends on the zoom level.
Is it possible to change the map center point, or make any changes that can make the map act as if that point (the green circle) is the center?
The purpose of this is that I want to drop a pin at (or move the current pin to) the pseudo-center point (the green one) every time the user drags the map. So to do this, I'd need to get the centerCoordinate (the red one) and then add an offset.

You can add layout margins for the map.
extension MKMapView {
/*
* This is to hide the legal link on the map.
*/
public func centerMapWithBottom(bottomPadding: CGFloat) {
self.layoutMargins = UIEdgeInsets(top: 0, left: 0, bottom: bottomPadding, right: 0)
}
}
This will shift the map center up. Similarly, it can be done for other scenarios as well.

Instead of showing user location for the map just drop an annotation pin at
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = myCoordinate; //CLLocationCoordinate2D myCoordinate
[self.mapView addAnnotation:point];

Related

Center MKMapView when part of map is covered

I have MKMapView which is from bottom covered by another view. Let's say the height of map is 250, but from bottom is 100 of it covered by other view.
Now, if I center the map using setRegion, it centers the map like if the whole map is visible, but I need to center it to region which is really visible, which is the rest 150 of height.
You can say, then lower the height of map to 150 so it won't be covered, but I need to have it covered by design, because the covering view does not have fully width to borders (there is gap from sides) so the map is visible around the covering view.
So, how to center the map for the height of the real visible region?
Now I am using this:
CLLocationCoordinate2D loc = CLLocationCoordinate2DMake(lat, long);
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance (loc, 200, 200);
[_map setRegion:region animated:YES];
Try using:
[theMapView setVisibleMapRect:[theMapView mapRectThatFits:theMapRect]
animated:YES];
Or, if you would like to adjust the screen offsets a bit further, you can use:
[theMapView setVisibleMapRect:[theMapView mapRectThatFits:theMapRect]
edgePadding:UIEdgeInsetsMake(50, 50, 50, 50)
animated:YES];
Not sure if you ever figured this out but here is a solution in swift. Should be easy to adapt for Obj-C
let pointYouWantCentered = CLLocationCoordinate2D(latitude: lat, longitude: lon)
pointYouWantCentered.latitude -= (mapView.region.span.latitudeDelta * 0.25)
mapView.setCenter(pointYouWantCentered, animated: true)
This will center the point in the top half of the screen. As long as you know the portion of the screen that your bottom view takes up you can adjust the center of the map to be on the point you want. For instance this is centering the point in the top half of the screen, assuming you have a view taking up the bottom half. If your bottom view took up 1/3 of the bottom and you wanted to center on the top 2/3 of the view you would do the following.
let pointYouWantCentered = CLLocationCoordinate2D(latitude: lat, longitude: lon)
pointYouWantCentered.latitude -= (mapView.region.span.latitudeDelta * (1.0/6.0))
mapView.setCenter(pointYouWantCentered, animated: true)
Hope this helps.

iOS: Best way to position my mapView to show the coordinates at the top left

I have the following code below that positions my mapView where it shows the coordinates in the center. However, I need it to position the mapView where it will show my coordinates at the top left. The code below is what I am currently using. I am using the category called MKMapView+ZoomLevel.h. If you need any more information please let me know.
[self.mapView setCenterCoordinate:coordinate zoomLevel:level animated:animated];
Get the region with self.mapView.region and find a new coordinate using some simple geometry. Region will give you the center point and the width and height of the view in degrees of latitude and longitude.
From there, you can determine a center coordinate to provide to the map view that will set your original coordinate in the upper left corner.
CLLocationCoordinate2DMake(self.mapView.coordinate.latitude +
self.mapView.region.span.latitudeDelta / 2,
self.mapView.coordinate.longitude +
self.mapView.region.span.longitudeDelta / 2)

set current location icon lower side in MKMapView

I want to show my current location lower in the map (iOS 6 and iOS 7) as per below screen shot to user can see further view [google default app with google map].
Right now, the cursor that shows center in the view as per below image [my app with apple map] .
Therefore the largest part of the screen is used to display what's behind, while it cannot look forward very far.
In the first image and second image, I compare to Google Navigation, which shows the current position much lower in the screen, for about the same rotation angle. I've added some arrows to show what I'm talking about.
i tried below code for set center because i cannot find to set lower.
mapView.userTrackingMode = MKUserTrackingModeFollow;
and also try below method
[mapView setCenterCoordinate:currentLocation.coordinate animated:YES];
Setting layoutMargins on MKMapView works just fine.
According to docs,
The default spacing to use when laying out content in the view.
In iOS 11 and later, use the directionalLayoutMargins property to
specify layout margins instead of this property.
To offset camera's centering point to be centered in bottom half of the MKMapView, just set UIEdgeInsets.top to half of MKMapView's height.
class MapViewController: UIViewController {
#IBOutlet var mapView: MKMapView!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let layoutMargins = UIEdgeInsets(top: self.mapView.bounds.size.height / 2, left: 0, bottom: 0, right: 0)
self.mapView.layoutMargins = layoutMargins
}
Don't set the userTrackingMode or the map's centerCoordinate.
Instead, you can try pointing the MKMapCamera to a coordinate slightly ahead of the user's in the direction they are heading. This will automatically put the user's location lower on the screen.
Calculating the coordinate "a short distance ahead" is not currently built into the iOS SDK so you'd have to calculate it manually.
One way to do it is using the method shown in:
Calculate new coordinate x meters and y degree away from one coordinate.
Using the coordinateFromCoord:atDistanceKm:atBearingDegrees: method from that answer, you could set the camera like this:
MKMapCamera *cam = [MKMapCamera camera];
CLLocationCoordinate2D coordinateAhead =
[self coordinateFromCoord:currentLocation.coordinate
atDistanceKm:0.15
atBearingDegrees:currentLocation.course];
//adjust distance (0.15 km) as needed
cam.centerCoordinate = coordinateAhead;
cam.heading = currentLocation.course;
cam.pitch = 80; //adjust pitch as needed (0=look straight down)
cam.altitude = 100; //adjust as needed (meters)
[mapView setCamera:cam animated:YES];
Try this with the "City Bicycle Ride", "City Run", or "Freeway Drive" in the simulator.
You may need to adjust some of the numbers to get the perspective you want.
A simple workaround that should work is to make the MKMapView frame bigger than the screen of the device.
Something like:
MapViewHeight = (WindowHeight - desiredOffsetFromBottom)*2

Is it possible to position a map view such that the user's current position is not in the center of the view?

I'm drawing a map within a view covering the entire device screen space.
On top of this view is another view occupying the bottom half of the screen. The top view is semi transparent and so the user can see the covered map beneath it.
Within the map I am displaying the user's current location.
The map view is automatically positioning the map such that the user's location is centered within the view - which is therefore the center of the device screen, however the center is also covered by the top view.
However I would like the user's location to be centered within the part of the map view that is not covered by the top view.
The simplest solution is to apply an offset to a coordinate to shift the map a little bit, taking advantage of the span of the region of the MKMapView.
CLLocationCoordinate2D newCenter = userCoordinate;
newCenter.latitude -= _mapView.region.span.latitudeDelta * 0.50;
[self.mapView setCenterCoordinate:newCenter animated:YES];
Value of 0.50 is there just to give you an example. By changing it you can adjust the offset.
You can also take the current center position, convert it to a CGPoint, then add desired offset in pixels to a CGPoint and convert it back to CLLocationCoordinate2D:
UIOffset offset = UIOffsetMake(30.0f, 40.0f);
offset.horizontal
offset.vertical
CGPoint point = [_mapView convertCoordinate:userCoordinate
toPointToView:_mapView];
point.x += offset.horizontal;
point.y += offset.vertical;
CLLocationCoordinate2D newCenter = [_mapView convertPoint:point
toCoordinateFromView:_mapView];
[_mapView setCenterCoordinate:newCenter animated:YES];
Hope it helps.

Moving an MKMapView to a specific location relative to the superview

I have a few annotations added to a MKMapView, and when the user clicks on one of the annotations, it displays a UICalloutView with a right accessory button which adds a UIView to the map, displaying some information about that specific location. This UIView is centred in the superview of the map, and in order to show that the information in that view is relative to the annotation, I would like to shift the visible map rect down (on the y axis), and center it on the x axis so that the annotation is directly under the view.
I am doing the following to centre the annotation, however, I don't know how to move the annotation down on the y axis so that it sits under the added UIView. Please can you tell me how I can do so?
[self.mapView setCenterCoordinate:[annotation coordinate] animated:YES];
If you want to shift the map down so it's centered on a particular coordinate, but shift it down, say, 40%, so you have space for something above it, you could do something like the following:
CLLocationCoordinate2D center = coordinate;
center.latitude -= self.mapView.region.span.latitudeDelta * 0.40;
[self.mapView setCenterCoordinate:center animated:YES];
You can get the size of the information view, then you know how much you want to use the map (based on the difference between its size and the map view size). Now you know the offset, you can calculate the point (in the view coordinate system) that should be moved to the centre so that the annotation is moved down). Then you can use convertPoint:toCoordinateFromView: to find the coordinate for that point to use with setCenterCoordinate:animated:.

Resources