Location Specification with an iOS MapView - ios4

Using an iOS device, I am interested in tapping a mapview and getting back the lat / long coordinates of that spot. Is this possible?

You can get the CLLocationCoordinate2D using convertPoint:toCoordinateFromView method of the MKMapView.
CLLocationCoordinate2D coordinate = [self.mapView convertPoint:[gesture locationInView:self.mapView] toCoordinateFromView:self.mapView];
I put this in a tap gesture handler to work. But if you are using some other mechanism to get the touch point, you can use the touch point as the argument passed in convertPoint:.

Related

CScrollView Offset Client Rect with Scroll Position

I am trying to write a function that will work out if the window that currently has focus is entirely shown in the client rect of my CScrollView but I am struggling to work out what I am doing wrong. This is what I have thus far:
CWnd * pWnd = pView->GetFocus();
if(pWnd)
{
CRect winRect;
pWnd->GetWindowRect(&winRect);
pView->ScreenToClient(&winRect); //pView is a pointer the CScrollView
CRect viewRect;
pView->GetClientRect(&viewRect);
CPoint currentScrollPoint = pView->GetScrollPosition();
viewRect.OffsetRect(currentScrollPoint);
if(!(viewRect.PtInRect(winRect.BottomRight()) && viewRect.PtInRect(winRect.TopLeft())))
{
//Not shown fully
}
}
Can anyone see what I am doing wrong here or suggest a better way of doing this?
The comments to the question above cleared up the actual intent of the question:
...when I tab to one that is not shown by the current client rect I want to scroll
to display that `CEdit`...
I found two articles searching MSDN for CFormView scroll tab key:
the first one uses OnCtlColor() to check if a sub-window has the focus and is not in view; it uses ScrollToPosition()
the second one mentions that ScrollToPosition() does not work in Windows CE (both the articles are quite old!), checks for WM_KEYUP of the tab key in PreTranslateMessage() and uses it's own ScrollToPos() function to scroll the control into view (this article was meant for Windows CE and you will need to replace wce_GetNextWindow by GetNextWindow

How to draw a map using mkmapview with driving directions between map annotations

I'm developing an App with some maps functionalities (among other things), I'd like to draw a map from my current location to a given destination, but I do not want to use the shareadapplication, The shared application does not have a BACK button for example and some other navigation items I already have.
I want to do it in my own viewcontroller with mkmapview on it.
I already have the code to place the pin annotations, what I need is to trace the driving directions from A to B.
The other option is to use the [[UIApplication sharedApplication] openURL:url] call to appear inside the viewcontroller window so I can keep my navigation items.
Any ideas?
thnxs
You can't do the "other option". iOS apps do not run inside windows that you can put within your app, they are full screen apps and you can make you app switch to them, but you can't make other apps switch back to yours.
So, the big question is, where are you going to get driving directions from? Check out GoogleMapsSDK, OpenStreetMap and CloudMade, because iOS maps won't give you the directions.

MKMapView Zoom to Annotations - annotationVisibleRect

Does anyone have an example of how to zoom an MKMapView to the area of all visible annotations using the annotationVisibleRect property on MKMapView? I have seen this post which offers a decent solution, but it seems that this annotationVisibleRect property would be the simplest solution.
Short answer: There is not a solution to this problem using annotationVisibleRect.
There is no example because this property cannot be used in this way. The limited documentation provided for it is certainly misleading for someone who is looking for something convenient from MapKit to do a somewhat common task.
annotationVisibleRect is the rect with regard to the MKAnnotationContainerView coordinate system. MKAnnotationContainerView is the superview for your annotations. If you look in MKMapView.h, you'll find this:
// annotationVisibleRect is the visible rect where the annotations views are currently displayed.
// The delegate can use annotationVisibleRect when animating the adding of the annotations views in mapView:didAddAnnotationViews:
#property (nonatomic, readonly) CGRect annotationVisibleRect;
Its specific purpose is for manipulation (animation) of the annotation views by providing a rectangle in their superview's coordinate system that matches the map view's viewport.
You might think (as I did) that this or similar will do the trick:
CGRect visibleRect = self.mapView.annotationVisibleRect;
MKCoordinateRegion visibleRegion = [self.mapView convertRect:visibleRect toRegionFromView:self.mapView];
[self.mapView setRegion:visibleRegion animated:YES];
It won't. Calling setRegion:animated: may cause the application to crash because the "fromView" is the incorrect coordinate system and may cause the latitude or longitude to go over their min/max values. You'd actually have to do something like this:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
if(views.count > 0) {
MKAnnotationView *view = [views objectAtIndex:0];
CGRect visibleRect = self.mapView.annotationVisibleRect;
MKCoordinateRegion visibleRegion = [self.mapView convertRect:visibleRect toRegionFromView:view.superview];
[self.mapView setRegion:visibleRegion animated:YES];
}
}
This won't crash the application, but it won't change the region either. If you compare visibleRegion to self.mapView.region, you will find that they are identical. That is because the annotationVisibleRect represents the same area that is visible in the map view -- just in a different coordinate system to make it convenient for you to do things like make the map pins come flying in from the edge of the view. See this answer for details on how it is used.
Also, for reference, here's where the MKAnnotationView sits in relation to MKMapView:
MKMapView
+-UIView
+-MKScrollContainerView
+-MKAnnotationContainerView <-- coordinate system of annotationVisibleRect
+-MKAnnotationView
Hope that helps clear some things up -- if not, ask away.
SWIFT 4
I think what your looking for is
mapView.showAnnotations(annotations:[MKAnnotation], animated: Bool)
You simply pass in an array of all the annotations you're trying to show which is the MKMapView.annotations
mapView.showAnnotations(mapView.annotations, animated: true)

Monotouch - programming for Swipe Gesture

I am developing a control for an IPAD application (My first time doing Apple development). Its a simple control that mimics a grid - consists of a collection of UIViews (each of which represents a cell) all added to a parent UIView (in a grid like fashion).
One of the requirements is to implement a swipe gesture - the users swipe across the grid to activate/inactivate the cell - this corresponds to a 1/0 in the database.
I create a UISwipeGesture and added it to each of my UIView which represents a cell. That appears to be an incorrect approach as it fires the event for the UIView in which the swipe originated but not across all the UIViews.
My understanding would be that i need to implement the SwipeGesture across the parent UIView which contains all these children UIView. However if i do that how will i know which child UIView has been swiped over? Or any other approach which would make sense?
I know this thread is fairly old, but I created a Swipe extension method that might have helped.
View.Swipe(UISwipeGestureRecognizerDirection.Right).Event += Swipe_Event;
void Swipe_Event(ViewExtensions.SwipeClass sender, UISwipeGestureRecognizer recognizer)
{
View view = sender.View; // do something with view that was swiped.
}
This may not answer your question, but I can speak to the approach I've taken here with a similar use case:
1) I would abandon UIScrollView and use UITableView. You'll notice that UITableView inherits from UIScrollView and has all the performance benefits of virtualization and cell / view re-use. Which you'll find terribly useful as you work towards optimizing your app for performance on device.
2) Utilize the UITableViewCell's ContentView to create custom "Grid" cells. Or better yet, utilize MonoTouch.Dialog if you're not required to create Grid rows ad-hoc.
3) Use this awesome class (props to #praeclarum) to setup gestures in MonoTouch. You essentially provide a UIGestureRecognizer as a generic argument. You can then utilize the LocationInView method to grab the point in the UITableView where the gesture occurred
public void HandleSwipe(UISwipeGestureRecognizer recognizer)
{
if(recognizer.State == UIGestureRecognizerState.Ended) {
var point = recognizer.LocationInView(myTableView);
var indexPath = myTableView.IndexPathForRowAtPoint(point);
// do associated calculations here
}
}
I think you're correct that the gesture recognizer has to be attached to the parent view. In the action method associated with the gesture recognizer I think you can use the Monotouch equivalent of CGRectContainsPoint() to determine whether the swipe occurred in a particular subview. I imagine you would have to iterate through the subviews until you found the one in which the swipe occurred. I'm not aware of a method that would immediately identify the swiped subview.

UIScroller inside UIWebView

Does any one have an idea how to access the UIScroller class , which is the default subview of UIWebView ?
I want to handle the touches, zooming , panning and scrolling features inside the webview .
Thanks..
I know this thread is old but if anyone comes across it there's a new way.
As of iOS 5 UIWebView now has a property called scrollView which you can't replace but you can set the properties of it. Most people just want to disable zooming/bouncing/scrolling all together which can be done by setting the properties of the scrollView for example if webview is a UIWebView:
webview.scrollView.bounces = NO; //Disables webview from bouncing
webview.scrollView.minimumZoomScale = webview.scrollView.maximumZoomScale = 1.0; //Forces zoom to be at 1 (can be whatever you fancy) and disables zooming
webview.scrollView.bouncesZoom = NO; //Disables bouncing when zooming exceeds minimum or maximum zoom
I suppose you could set the delegate for the scrollView if you want more control, though to be on the safe side you might want to store the original delegate and call its methods appropriately in your custom delegate.
Handling the touches would be more difficult since you can't replace the scrollView to provide your own handlers. Best you could do is add some gesture recognizers as part of the UIView and try to handle them there, but I think UIWebView will still receive the events. Alternatively in iOS 5 they let you access the gesture recognizers directly on UIScrollView.
You can find this by going like this:
[webview objectAtIndex:0]
That should be where it is. If not, put this in your code somewhere and run the program to search for the index of the UIScroller, and replace the 0 above with that index:-
for (UIView *subview in [webView subviews]){
NSLog(#"subviews of webView : %#", [[subview class] description]);
}

Resources