Как перехватить события касаний на объектах MKMapView или UIWebView? - PullRequest
96 голосов
/ 26 июня 2009

Я не уверен, что делаю неправильно, но я пытаюсь уловить прикосновения к MKMapView объекту. Я вложил его в подкласс, создав следующий класс:

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

@interface MapViewWithTouches : MKMapView {

}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event;   

@end

И реализация:

#import "MapViewWithTouches.h"
@implementation MapViewWithTouches

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *) event {

    NSLog(@"hello");
    //[super touchesBegan:touches   withEvent:event];

}
@end

Но похоже, что когда я использую этот класс, я ничего не вижу на консоли:

MapViewWithTouches *mapView = [[MapViewWithTouches alloc] initWithFrame:self.view.frame];
[self.view insertSubview:mapView atIndex:0];

Есть идеи, что я делаю не так?

Ответы [ 14 ]

0 голосов
/ 15 декабря 2009

Вот то, что я собрал, это позволяет увеличивать масштаб в симуляторе (еще не пробовал на реальном iPhone), но я думаю, что все будет в порядке:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Began %d", [touches count]);
 reportTrackingPoints = NO;
 startTrackingPoints = YES;
    [viewTouched touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
 if ([[event allTouches] count] == 2) {
  reportTrackingPoints = YES;
  if (startTrackingPoints == YES) {
   BOOL setA = NO;
   NSEnumerator *enumerator = [[event allTouches] objectEnumerator];
   id value;
   while ((value = [enumerator nextObject])) {
    if (! setA) {
     startPointA = [value locationInView:mapView];
     setA = YES;
    } else {
     startPointB = [value locationInView:mapView];
    }
   }
   startTrackingPoints = NO;
  } else {
   BOOL setA = NO;
   NSEnumerator *enumerator = [[event allTouches] objectEnumerator];
   id value;
   while ((value = [enumerator nextObject])) {
    if (! setA) {
     endPointA = [value locationInView:mapView];
     setA = YES;
    } else {
     endPointB = [value locationInView:mapView];
    }
   }
  }
 }
 //NSLog(@"Touch Moved %d", [[event allTouches] count]);
    [viewTouched touchesMoved:touches withEvent:event];
}

- (void) updateMapFromTrackingPoints {
 float startLenA = (startPointA.x - startPointB.x);
 float startLenB = (startPointA.y - startPointB.y);
 float len1 = sqrt((startLenA * startLenA) + (startLenB * startLenB));
 float endLenA = (endPointA.x - endPointB.x);
 float endLenB = (endPointA.y - endPointB.y);
 float len2 = sqrt((endLenA * endLenA) + (endLenB * endLenB));
 MKCoordinateRegion region = mapView.region;
 region.span.latitudeDelta = region.span.latitudeDelta * len1/len2;
 region.span.longitudeDelta = region.span.longitudeDelta * len1/len2;
 [mapView setRegion:region animated:YES];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
 if (reportTrackingPoints) {
  [self updateMapFromTrackingPoints];
  reportTrackingPoints = NO;
 }


    [viewTouched touchesEnded:touches withEvent:event];
}

Основная идея заключается в том, что если пользователь использует два пальца, вы отслеживаете значения. Я записываю начальную и конечную точки в startPoints A и B. Затем я записываю текущие точки отслеживания, и когда я закончу, на touchesEnded я могу вызвать подпрограмму для вычисления относительной длины линии между точками, с которых я начинаю и линия между точкой I заканчивается с помощью простого вычисления гипотенузы. Соотношение между ними - величина увеличения: я умножаю область на эту величину.

Надеюсь, это кому-нибудь пригодится.

0 голосов
/ 15 декабря 2009

Я заметил, что вы можете отслеживать количество и местоположение касаний и получать местоположение каждого в представлении:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"Touch Moved %d", [[event allTouches] count]);

 NSEnumerator *enumerator = [touches objectEnumerator];
 id value;

 while ((value = [enumerator nextObject])) {
  NSLog(@"touch description %f", [value locationInView:mapView].x);
 }
    [viewTouched touchesMoved:touches withEvent:event];
}

Кто-нибудь еще пытался использовать эти значения для обновления уровня масштабирования карты? Это будет вопрос записи начальных позиций, а затем финишных мест, расчета относительной разницы и обновления карты.

Я играю с базовым кодом, предоставленным Мартином, и похоже, что он будет работать ...

0 голосов
/ 22 июля 2009

Спасибо за пиццу и крики - вы сэкономили мне много времени.

multipleouchenabled будет работать время от времени.

viewTouch.multipleTouchEnabled = TRUE;

В конце концов, я переключил виды, когда мне нужно было захватить касание (другой момент времени, чем нуждающийся в пинчзуме):

    [mapView removeFromSuperview];
    [viewTouch addSubview:mapView];
    [self.view insertSubview:viewTouch atIndex:0];
0 голосов
/ 27 июня 2009

Сделайте MKMapView подпредставлением пользовательского представления и внедрите

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

в пользовательском представлении, чтобы вернуть self вместо подпредставления.

...