Я нашел лучший способ добиться этого с помощью распознавателя жестов. Оказывается, что другие способы включают в себя множество хакерских программ, которые несовершенно дублируют код Apple, особенно в случае мультитач.
Вот что я делаю: реализую распознаватель жестов, который нельзя предотвратить и который не может предотвратить другие распознаватели жестов. Добавьте его в представление карты, а затем используйте touchesBegan, touchesMoved и т. Д. Для gestureRecognizer по своему усмотрению.
Как обнаружить любой кран внутри MKMapView (без трюков)
WildcardGestureRecognizer * tapInterceptor = [[WildcardGestureRecognizer alloc] init];
tapInterceptor.touchesBeganCallback = ^(NSSet * touches, UIEvent * event) {
self.lockedOnUserLocation = NO;
};
[mapView addGestureRecognizer:tapInterceptor];
WildcardGestureRecognizer.h
//
// WildcardGestureRecognizer.h
// Copyright 2010 Floatopian LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef void (^TouchesEventBlock)(NSSet * touches, UIEvent * event);
@interface WildcardGestureRecognizer : UIGestureRecognizer {
TouchesEventBlock touchesBeganCallback;
}
@property(copy) TouchesEventBlock touchesBeganCallback;
@end
WildcardGestureRecognizer.m
//
// WildcardGestureRecognizer.m
// Created by Raymond Daly on 10/31/10.
// Copyright 2010 Floatopian LLC. All rights reserved.
//
#import "WildcardGestureRecognizer.h"
@implementation WildcardGestureRecognizer
@synthesize touchesBeganCallback;
-(id) init{
if (self = [super init])
{
self.cancelsTouchesInView = NO;
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (touchesBeganCallback)
touchesBeganCallback(touches, event);
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)reset
{
}
- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event
{
}
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer
{
return NO;
}
- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
{
return NO;
}
@end
SWIFT 3
let tapInterceptor = WildCardGestureRecognizer(target: nil, action: nil)
tapInterceptor.touchesBeganCallback = {
_, _ in
self.lockedOnUserLocation = false
}
mapView.addGestureRecognizer(tapInterceptor)
WildCardGestureRecognizer.swift
import UIKit.UIGestureRecognizerSubclass
class WildCardGestureRecognizer: UIGestureRecognizer {
var touchesBeganCallback: ((Set<UITouch>, UIEvent) -> Void)?
override init(target: Any?, action: Selector?) {
super.init(target: target, action: action)
self.cancelsTouchesInView = false
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
touchesBeganCallback?(touches, event)
}
override func canPrevent(_ preventedGestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}
override func canBePrevented(by preventingGestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}
}
video
тег HTML5 с элементами управления, распознаватель жестов не позволит пользователю использовать элементы управления. Я искал обходной путь для этого, но еще не нашел его.После дня пиццы и криков я наконец нашел решение! Очень аккуратный!
Питер, я использовал ваш трюк выше и немного изменил его, чтобы наконец получить решение, которое отлично работает с MKMapView и должно также работать с UIWebView.
MKTouchAppDelegate.h
MKTouchAppDelegate.m
UIViewTouch.h
UIViewTouch.m
Я надеюсь, что это поможет некоторым из вас!
Ура
источник
источник
Для MKMapView настоящее рабочее решение - распознавание жестов!
Я хотел перестать обновлять центр карты относительно моего местоположения, когда я перетаскиваю карту или зажимаю пальцы для увеличения.
Итак, создайте и добавьте свой распознаватель жестов в mapView:
Посмотрите ссылку на класс UIGestureRecognizer, чтобы увидеть все доступные средства распознавания жестов.
Поскольку мы определили делегата для себя, мы должны реализовать протокол UIGestureRecognizerDelegate:
И переопределите метод gestureRecognizer: gestureRecognizer shouldRecognizeSimuallyWithGestureRecognizer: чтобы разрешить одновременное распознавание нескольких жестов, если я правильно понял:
Теперь напишите методы, которые будут вызываться нашими распознавателями жестов:
источник
На всякий случай кто-то пытается сделать то же самое, как я: я хотел создать аннотацию в точке, где пользователь нажимает. Для этого я использовал
UITapGestureRecognizer
решение:Однако
didTapOnMap:
он также вызывался, когда я нажимал на аннотацию и создавал новую. Решение состоит в том, чтобы реализоватьUIGestureRecognizerDelegate
:источник
MKAnnotation
. В этом случае у вас может быть подпредставление другой аннотации, запускающее распознаватель жестов. Мне пришлось рекурсивно проверить супервизор touch.view, чтобы найти потенциальный MKAnnotationViewВам, вероятно, потребуется наложение прозрачного представления, чтобы улавливать касания, как это часто делается с элементами управления на основе UIWebView. Просмотр карты уже выполняет ряд специальных функций касанием, чтобы можно было перемещать карту, центрировать, масштабировать и т. Д., Чтобы сообщения не попадали в ваше приложение.
Я могу придумать еще два (НЕПРОВЕРЕННЫХ) варианта:
1) Подайте в отставку первого респондента через IB и установите для него значение «Владелец файла», чтобы позволить владельцу файла отвечать на прикосновения. Я сомневаюсь, что это сработает, потому что MKMapView расширяет NSObject, а не UIView, и в результате события касания все еще могут не распространяться на вас.
2) Если вы хотите поймать при изменении состояния карты (например, при увеличении), просто реализуйте протокол MKMapViewDelegate для прослушивания определенных событий. Я предполагаю, что это ваш лучший способ легко захватить какое-либо взаимодействие (если не считать реализации прозрачного вида поверх карты). Не забудьте установить View Controller, содержащий MKMapView, в качестве делегата карты (
map.delegate = self
).Удачи.
источник
Я не экспериментировал, но есть большая вероятность, что MapKit основан на кластере классов, и поэтому создание его подклассов сложно и неэффективно.
Я бы предложил сделать представление MapKit подвидом пользовательского представления, которое должно позволить вам перехватывать события касания до того, как они достигнут его.
источник
Итак, после полдня возиться с этим я обнаружил следующее:
В видеороликах Stanford iPhone парень из Apple говорит, что многие вещи UIKit вызовут множество ошибок, если вы «передадите» запросы касания (то есть два метода, описанных выше), и вы, вероятно, не заставите его работать.
РЕШЕНИЕ : описано здесь: Перехват / захват событий касания iPhone для MKMapView . По сути, вы «ловите» событие до того, как его получит ответчик, и интерпретируете его там.
источник
В Swift 3.0
источник
Сделайте MKMapView подвидом пользовательского представления и реализуйте
в пользовательском представлении, чтобы вернуть self вместо subview.
источник
Спасибо за пиццу и крики - вы сэкономили мне много времени.
multitouchenabled будет работать время от времени.
В конце концов, я отключил виды, когда мне нужно было уловить прикосновение (другой момент времени, чем когда мне нужны щипки):
источник
Я заметил, что вы можете отслеживать количество и расположение касаний и получать местоположение каждого в виде:
Кто-нибудь еще пробовал использовать эти значения для обновления уровня масштабирования карты? Это будет вопрос записи начальных позиций, а затем конечных точек, вычисления относительной разницы и обновления карты.
Я играю с базовым кодом, предоставленным Мартином, и похоже, что он будет работать ...
источник
Вот то, что я собрал, что позволяет увеличивать масштаб в симуляторе (не пробовал на настоящем iPhone), но я думаю, что все будет хорошо:
Основная идея заключается в том, что если пользователь использует два пальца, вы отслеживаете значения. Я записываю начальную и конечную точки в startPoints A и B. Затем я записываю текущие точки отслеживания, и когда я закончу, на touchesEnded я могу вызвать процедуру для вычисления относительной длины линии между точками, с которых я начинаю. , а линия между точкой I заканчивается простым вычислением гипотенузы. Соотношение между ними и есть величина увеличения: я умножаю диапазон области на эту величину.
Надеюсь, это кому-то пригодится.
источник
Я взял идею «оверлейного» прозрачного представления из ответа MystikSpiral, и он отлично сработал для того, чего я пытался достичь; быстрое и чистое решение.
Короче говоря, у меня был собственный UITableViewCell (разработанный в IB) с MKMapView слева и некоторыми UILabels справа. Я хотел сделать пользовательскую ячейку, чтобы вы могли касаться ее где угодно, и это подтолкнуло бы к новому контроллеру представления. Однако прикосновение к карте не передавало касаний «вверх» UITableViewCell, пока я просто не добавил UIView того же размера, что и вид карты, прямо поверх него (в IB) и не сделал его фоном «прозрачным цветом» в коде ( не думаю, что вы можете установить clearColor в IB ??):
Думал, что это может помочь кому-то другому; конечно, если вы хотите добиться того же поведения для ячейки табличного представления.
источник