Aktivieren von touchEvents (scroll-und pan) in MKMapview unten eine benutzerdefinierte UIView?
alt-text http://www.gisnotes.com/wordpress/wp-content/uploads/2009/09/poly.png
In einer nussschale, ich bin versucht, herauszufinden, wie der Skalierung der geometrie (Punkt, Linie, polygon) implementiert, die in einer benutzerdefinierten Ansicht (geometryView) auf der Oberseite von MKMapView (mapView).
, Was ich Tat, war..
-
Erstellen DrawMapViewController. Fügen Sie die UIBarButtonItems (KARTE, PT, LN, PG) auf der unteren Symbolleiste.
-
Wenn Sie auf anzeigen klicken, werden Sie in der Lage sind zu schwenken/Zoomen auf der Karte. Dadurch können die Kartenansicht durch setzen des geometryView.hidden = YES;
-
Wenn eine der drei geometrie-buttons geklickt wird, wird die geometryView angezeigt wird geometryView.hidden = NEIN, so touchEvents und zeichnen der geometrie von GeometryView.drawRect Methode.
Layer-Reihenfolge ist wie folgt: mapView ist an der Unterseite geometryView.
-geometryView
-mapView
Was ist mein problem?
Im Idealfall, während des "map" - Modus und wenn der Benutzer schwenken und Zoomen, ich bin der Hoffnung, wenn möglich, seine Darstellung der Zeichnung von geometryView. Aber, wenn der Benutzer trifft "anzeigen", dann geometryView.hidden = YES, so wird die Zeichnung verschwindet. Wenn ich geometryView sichtbar ist, dann interagiert der Benutzer mit geometryView nicht mapView, so gibt es kein Zoomen und schwenken.
Ist es möglich, zu behandeln touchEvents (pan/zoom) von MKMapView unten eine benutzerdefinierte Ansicht, während die benutzerdefinierte Ansicht wird angezeigt? Irgendwelche anderen Ideen/Ansätze sehr dankbar.
Dank,
Rupert
GeometryView Auflistung:
@synthesize mapview, pinFactory;
- (id)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
}
return self;
}
- (void)drawRect:(CGRect)rect {
//Drawing code
NSLog(@"DrawRect called");
CGContextRef context = UIGraphicsGetCurrentContext();
//Drawing lines with a white stroke color
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
//Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(context, 2.0);
if(pinFactory.geometryState == 2){ //Draw Line
if( [pinFactory actualPinCount] > 1){
Pin *pin1 = (Pin *)[[pinFactory pinArray] objectAtIndex:0];
CGPoint pt1 = pin1.touchLocation;
CGContextMoveToPoint(context, pt1.x, pt1.y);
for (int i = 1; i < ([pinFactory actualPinCount]); i++)
{
Pin *pin2 = (Pin *)[[pinFactory pinArray] objectAtIndex:i];
CGPoint pt2 = pin2.touchLocation;
CGContextAddLineToPoint(context, pt2.x, pt2.y);
}
CGContextStrokePath(context);
}
}
else if(pinFactory.geometryState == 3){ //Draw Polygon
//if there are two points, draw a line first.
//if there are three points, fill the polygon
if( [pinFactory actualPinCount] == 2){
Pin *pin1 = (Pin *)[[pinFactory pinArray] objectAtIndex:0];
CGPoint pt1 = pin1.touchLocation;
CGContextMoveToPoint(context, pt1.x, pt1.y);
Pin *pin2 = (Pin *)[[pinFactory pinArray] objectAtIndex:1];
CGPoint pt2 = pin2.touchLocation;
CGContextAddLineToPoint(context, pt2.x, pt2.y);
CGContextStrokePath(context);
}
else if([pinFactory actualPinCount] > 2){
//fill with a blue color
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
Pin *pin1 = (Pin *)[[pinFactory pinArray] objectAtIndex:0];
CGPoint pt1 = pin1.touchLocation;
CGContextMoveToPoint(context, pt1.x, pt1.y);
for (int i = 1; i < ([pinFactory actualPinCount]); i++)
{
Pin *pin2 = (Pin *)[[pinFactory pinArray] objectAtIndex:i];
CGPoint pt2 = pin2.touchLocation;
CGContextAddLineToPoint(context, pt2.x, pt2.y);
}
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
}
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self setNeedsDisplay];
UITouch* aTouch = [touches anyObject];
location = [aTouch locationInView:self];
NSLog(@"touchesBegan: x:%f, y:%f", location.x, location.y );
CLLocationCoordinate2D coordinate = [mapview convertPoint:location toCoordinateFromView:self];
switch (pinFactory.geometryState) {
case 1:{
if( [pinFactory actualPinCount] == 1){
//[UIView beginAnimations:@"stalk" context:nil];
//[UIView setAnimationDuration:1];
//[UIView setAnimationBeginsFromCurrentState:YES];
Pin *pin = (Pin *)[pinFactory getObjectAtIndex:0];
[mapview removeAnnotation:pin];
[pinFactory removeObject:pin];
Pin *newPin = [[Pin alloc] initWithCoordinate:coordinate initLocation:location withTitle:@"My Pin"];
[pinFactory addObject:newPin];
[mapview addAnnotation:newPin];
[newPin release];
//[UIView commitAnimations];
}
else{
//Lets add a new pin to the geometry
Pin *pin = [[Pin alloc] initWithCoordinate:coordinate initLocation:location withTitle:@"My Pin"];
[pinFactory addObject:pin];
[mapview addAnnotation:pin];
[pin release];
}
break;
}
case 2:{
//Lets add a new pin
Pin *pin = [[Pin alloc] initWithCoordinate:coordinate initLocation:location withTitle:@"My Pin"];
[pinFactory addObject:pin];
[mapview addAnnotation:pin];
[pin release];
[self setNeedsDisplay];
break;
}
case 3:{
//Lets add a new pin
Pin *pin = [[Pin alloc] initWithCoordinate:coordinate initLocation:location withTitle:@"My Pin"];
[pinFactory addObject:pin];
[mapview addAnnotation:pin];
[pin release];
[self setNeedsDisplay];
break;
}
default:
break;
}
}
- (void)dealloc {
[super dealloc];
}
@end
DrawMapViewController Auflistung:
#import "DrawMapViewController.h"
#import "Pin.h"
@implementation DrawMapViewController
@synthesize mapview, mapBarButton, pointBarButton, lineBarButton, polygonBarButton, geometryView;
/* State represents state of the map
* 0 = map
* 1 = point
* 2 = line
* 3 = polygon
*/
//The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
//Custom initialization
self.title = @"Map";
}
return self;
}
//Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
mapview.mapType = MKMapTypeSatellite;
NSMutableArray *pinArray = [[NSMutableArray alloc] initWithObjects:nil];
pinFactory = [[PinFactory alloc] initWithArray:pinArray];
pinFactory.map = mapview;
[pinArray release];
geometryView = [[GeometryView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 372.0f)];
geometryView.pinFactory = pinFactory;
geometryView.mapview = mapview;
geometryView.backgroundColor = [UIColor clearColor];
[self.view addSubview:geometryView];
[self changeButtonAndViewState:0];
}
/*
//Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
//Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
//Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
//Release any retained subviews of the main view.
//e.g. self.myOutlet = nil;
}
- (void)dealloc {
[mapBarButton release];
[pointBarButton release];
[lineBarButton release];
[polygonBarButton release];
[super dealloc];
}
- (IBAction)mapBarButtonPressed{
NSLog(@"mapBarButtonPressed");
[self changeButtonAndViewState:0];
}
- (IBAction)pointBarButtonPressed{
NSLog(@"pointBarButtonPressed");
[self changeButtonAndViewState:1];
if( [pinFactory actualPinCount] > 0){
[self resetGeometry];
}
}
- (IBAction)lineBarButtonPressed{
NSLog(@"lineBarButtonPressed");
if( [pinFactory actualPinCount] > 0){
[self resetGeometry];
}
[self changeButtonAndViewState:2];
}
- (IBAction)polygonBarButtonPressed{
NSLog(@"polygonBarButtonPressed");
if( [pinFactory actualPinCount] > 0){
[self resetGeometry];
}
[self changeButtonAndViewState:3];
}
- (void)resetGeometry{
NSLog(@"resetting geometry.. deleting all pins");
[mapview removeAnnotations:[pinFactory pinArray]];
NSMutableArray *array = [pinFactory pinArray];
[array removeAllObjects];
[geometryView setNeedsDisplay];
}
- (void)changeButtonAndViewState:(int)s{
[pinFactory setGeometryState:s];
mapBarButton.style = UIBarButtonItemStyleBordered;
pointBarButton.style = UIBarButtonItemStyleBordered;
lineBarButton.style = UIBarButtonItemStyleBordered;
polygonBarButton.style = UIBarButtonItemStyleBordered;
pointBarButton.enabled = YES;
lineBarButton.enabled = YES;
polygonBarButton.enabled = YES;
switch ([pinFactory geometryState]) {
case 0:{
mapBarButton.style = UIBarButtonItemStyleDone;
geometryView.hidden = YES;
break;
}
case 1:{
pointBarButton.enabled = NO;
pointBarButton.style = UIBarButtonItemStyleDone;
geometryView.hidden = NO;
break;
}
case 2:{
lineBarButton.enabled = NO;
lineBarButton.style = UIBarButtonItemStyleDone;
geometryView.hidden = NO;
break;
}
case 3:{
polygonBarButton.enabled = NO;
polygonBarButton.style = UIBarButtonItemStyleDone;
geometryView.hidden = NO;
break;
}
default:
break;
}
}
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animate{
NSLog(@"regionDidChangeAnimated");
}
@end
InformationsquelleAutor Rupert | 2009-09-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hey ich sehe hat niemand antwortete Sie, und ich gerade herausgefunden, wie dies zu tun. Leider können Sie keine Ereignisse abfangen und leiten Sie an die mapView so etwas wie
Dies ist, was Sie wollen zu tun, aber es WIRD NICHT FUNKTIONIEREN. Für einige Grund Sie nicht abfangen können der Karte die Ereignisse, und Sie können auch Umgekehrt Vorgehen und der Unterklasse, die MKMapView-und überlast-touch-Methoden. Die einzige Möglichkeit die ich gefunden habe, um dies zu tun, ist wie folgt.
Erstellen Sie Ihre MapOverlay anzeigen, legen Sie es auf einen transparenten hintergrund, und deaktivieren Sie berührt es. Überlagern diese auf Ihre MKMapView. Führen Sie dann die folgenden
Unterklasse UIWindow mit einer benutzerdefinierten Klasse, die wird uns alle berührt, um Ihre überlagerung, entweder Umgang mit der Logik, wie "wenn das overlay nicht verborgen, und dann nach vorne", oder in der überlagerung selbst halten Zustand. Jedenfalls sieht es so aus
Wenn Sie die Weiterleitung des Ereignisses an dem overlay, das Sie zuerst überprüfen, wenn die Details innerhalb Ihrer mapView region, dann herauszufinden, welche Art von Berührungen, die Sie sind, dann rufen Sie das richtige touch-Methode auf das overlay.
Glück!
InformationsquelleAutor DevDevDev
Ich weiß, diese Antwort kommt wahrscheinlich zu spät, aber ich nehme einen stab sowieso, für all diejenigen (wie mich), die haben auch dieses problem.
Die Klasse MKMapView touch-Ereignisse werden alle behandelt, die von einem UIScrollView intern. Erfassen Sie die Ereignisse von diesen Blättern anzeigen, indem Sie die MKMapView eine Untersicht einer benutzerdefinierten UIView, und die Bereitstellung Ihrer benutzerdefinierten berührt Methoden in der benutzerdefinierten Ansicht.
Der trick ist, den überblick zu behalten UIScrollView verwendet, durch die MKMapView. Um dies zu tun, ich überschrieb die "hitTest" - Methode, die zurückgibt, "selbst", was glaube ich bedeutet, dass diese benutzerdefinierte Ansicht soll die touch-Ereignisse.
Auch, die hitTest-Methode wird die UIScrollView die MKMapView. Auf meiner eigenen UIView ich nannte es "echo_to", weil die Ereignisse werden dann auch für die UIScrollView zu machen, die Karte funktioniert, wie es funktioniert in der Regel.
Viel Glück.
InformationsquelleAutor Tom
Abhängig von der Raffinesse Ihrer geometryView, Sie können möglicherweise verwenden Sie eine Beschriftungsansicht, um es zu zeichnen.
Der Nachteil dieses Ansatzes ist, dass die Sicht nicht Maßstab mit der Karte (obwohl Sie die
mapView:regionDidChangeanimated:
delegate-Methode zum Neuzeichnen nach zoom), aber es wird pan mit der Karte.InformationsquelleAutor Frank Schmitt
HitTest-trick funktioniert sehr gut, solange Sie nicht müssen Benutzer in der Lage sein, um Tippen Sie auf Anmerkungen oder pinch-and-zoom der Karte. Weder diese in der Lage sind, weitergeleitet werden.
InformationsquelleAutor avance