Tracking MKMapView centerCoordinate while panning - ios

I'm implementing a map feature in my app where I allow the user to set their current location by panning around.
All this time, I want to have an MKAnnotation in the centerCoordinate. So what I want to do is keep track of when the map's centerCoordinate changes and change the annotation's coordinate correctly. The behaviour would be similar to that of Uber, Hailo and others.
I tried a time based implementation where every 0.00001s the centerCoordinate would be checked and the annotation would also be moved. But if the map isn't flicked gently, the annotation jumps from one place to another which doesn't make for a good UI.
Another implementation I tried is by way of gesture recognisers and the delegate methods of MKMapView (regionDidChange/regionWillChange). This, again, makes for a very abrupt transition.
Can anyone please advise me on how to do this better?

I suggest not using an actual id<MKAnnotation> at all (at least for this "current location setting" mode).
Instead:
Add a view (eg. UIImageView) containing an image of a pin (or whatever icon you like) in front of the map view.
This pin view should not be a subview of the map view.
The pin view should be a subview of the same view that the map view is a subview of (eg. both should be subviews of the same superview).
The pin view should be sized and positioned such that it appears above the center of the map view (you could make the pin view have the same frame and the same autolayout/autoresizing logic as the map view so they stay visually synchronized regardless of screen size or orientation).
If using a UIImageView, set its content mode to "center" and background color to "clear" (default is clear).
The pin view should have user interaction disabled on it so that the user can still interact with the map view behind it. As the user pans or zooms the map view, the pin view in front will seem to move instantly.
If necessary, the app can get the location coordinates from mapView.centerCoordinate in the regionDidChangeAnimated: MKMapViewDelegate method (or pan/pinch gesture recognizers) or only when the user says they're done positioning. I don't recommend using a timer (especially every 0.00001s) to query the current center coordinate.
When the user indicates that the current position is where they want to finally place the annotation, you can then create and add an actual annotation at that coordinate and hide the "location setting mode" pin view.

Related

fix a MKPointAnnotation to centre of map (MapKit) even while user is scrolling

I need to fix an MKPointAnnotation to the center of the map even while the user is scrolling the map, it should still stay in middle. just like Ola app
By far I achieved searching, setting annotation to the center of the map and changing annotation to center again when user scrolls
however it updates when the user stops scrolling, but I want it to stay in the middle always so the user can scroll to an exact location.

MKMapView Swift : MKPointPointAnnotation Centre of screen

I'm trying to build a location selector in swift. The idea is :
When the map appears, an annotation pin appears at the user location. Then the user can change the location of the pin by moving the map around. (the pin stays at the centre of the screen. Like the uber app).
I have no issue spawning an annotation at the user location when the map loads. But I can't find a way to keep the pin at the centre of the screen when the user moves the map around.
I believe I must use regiondidChangeAnimated function, but I can`t find a way to update smoothly the position of the annotation.
Thank you for your help !
When you want some view to not move when you pan the map, just put it on the map view's superview (e.g. add a UIImageView to that superview), add the necessary constraints so that it's centered where you want it, and make sure that user interaction is disabled with that image view. Then you can pan the map and the image view will gracefully float there, above the map, not moving at all.

iOS Swift MKMapView set overlay in front of map, behind annotation view

Here's an image of what I'm trying to accomplish:
Basically, a "dimmed" map.
The problem: The user needs the capability to pan the map, so just adding a semi-transparent view over the map won't do. (Adding a view over the mapView means it won't be able to detect gestures.)
Things I've tried:
Setting mapView backgroundColor
Adding a semi-transparent view using mapView.insertSubview
Setting mapView alpha (affects all children, i.e. annotation views)
MKOverlay (I've only found ways to set a view/polygon by coordinates)
is it possible to subclass a view that you can add as a semi-transparent subview, and give it a new variable called "map". This map variable would be a reference to your actual map. Add gesture recognizers for the subview, and when some sort of gesture takes place, pass the gesture to the map.
or add the gesture recognizers to the subview, and in the gesture recognizer, say map.runFunctionForThatGesture
I haven't done this myself, but I think it should work

MKMapView center coordinates inside specific frame

Is there a way to center mapView on specific coordinates in specific mapView's frame?
Let me illustrate:
I have a centered pin:
At some point of time popup view may appear and I need to center my pin in visible mapView rect:
Moreover I have to do this during popup appearing animating (this is another issue since popup.frame is no KVO compliant)
What I have:
I've implemented fast-&-dirty solution by centering mapView on fake location.
Simply I copied fake coordinates from original and replaced latitude, this lets original pin to be on top of popup.
But this approach not really elegant and not accurate.
Important:
I can't change mapView's frame simple because popup has indents through which map is visible.

Sync zoom of UIImageView with UIScrollView's viewForZoomingInScrollView:

I'm developing some kind of custom map, which will present additional information above map content (I will call it overlay). But overlay rendering very hard process so I render only that part which user can see on the screen at this moment. But I also want when user zoom or pan map, overlay zoom and pan too (without re-rendering, of course, because it require a time to do it). So my overlay is UIView with UIImageView subview. During user pan I look for contentOffset changes (map content presents on UIScrollView) and move my imageView to that offset (change origin of it's frame), so this is very quickly. When user detach fingers from screen I set initial frame to imageView and re-render it. How can I do similar with zoom? I tried monitor for zoomScale changes and contentOffset, but imageView move not like map content. Any suggestion how to do it will be useful for me
I solved my by problem coming from another side to it. Instead of calculating offsets and zoom scales, I add overlay to map content as subview, so it moves and scales with it very good. When user detach fingers from map, I remove it from superview and re-render it

Resources