Cara terbaik yang saya temukan untuk mencapai ini adalah dengan Pengenal Gerakan. Cara lain ternyata melibatkan banyak program hackish yang secara tidak sempurna menduplikasi kode Apple, terutama dalam kasus multitouch.
Inilah yang saya lakukan: Menerapkan pengenal isyarat yang tidak dapat dicegah dan tidak dapat mencegah pengenal isyarat lainnya. Tambahkan ke tampilan peta, dan kemudian gunakan sentuhan gestureRecognizer'sBegan, touchesMoved, dll sesuai keinginan Anda.
Cara mendeteksi ketukan apa pun di dalam MKMapView (tanpa trik)
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
tag HTML5 dengan kontrol, pengenal isyarat akan mencegah pengguna untuk dapat menggunakan kontrol tersebut. Saya telah mencari solusi untuk ini tetapi belum menemukannya.Setelah seharian makan pizza, teriakan, akhirnya saya menemukan solusinya! Sangat rapi!
Peter, saya menggunakan trik Anda di atas dan mengubahnya sedikit untuk akhirnya memiliki solusi yang bekerja sempurna dengan MKMapView dan juga harus bekerja dengan UIWebView
MKTouchAppDelegate.h
MKTouchAppDelegate.m
UIViewTouch.h
UIViewTouch.m
Saya harap itu akan membantu beberapa dari Anda!
Bersulang
sumber
sumber
Untuk MKMapView, solusi yang berfungsi sebenarnya adalah dengan pengenalan gerakan!
Saya Saya ingin berhenti memperbarui pusat peta di lokasi saya ketika saya menyeret peta atau mencubit untuk memperbesar.
Jadi, buat dan tambahkan pengenal gerakan Anda ke mapView:
Lihat Referensi Kelas UIGestureRecognizer untuk melihat semua pengenal gerakan yang tersedia.
Karena kita telah mendefinisikan delegasi untuk dirinya sendiri, kita harus menerapkan protocole UIGestureRecognizerDelegate:
Dan menimpa metode gestureRecognizer: gestureRecognizer shouldRecognizeSimoraryouslyWithGestureRecognizer: untuk memungkinkan mengenali beberapa gerakan secara bersamaan, jika saya mengerti benar:
Sekarang tulis metode yang akan dipanggil oleh pengenal isyarat kami:
sumber
Untuk berjaga-jaga jika seseorang mencoba melakukan hal yang sama seperti saya: Saya ingin membuat anotasi pada titik di mana pengguna mengetuk. Untuk itu saya menggunakan
UITapGestureRecognizer
solusinya:Namun,
didTapOnMap:
juga dipanggil ketika saya mengetuk anotasi dan yang baru akan dibuat. Solusinya adalah dengan menerapkanUIGestureRecognizerDelegate
:sumber
MKAnnotation
. Dalam kasus ini, Anda mungkin memiliki subview anotasi lain yang memicu pengenal isyarat. Saya harus secara rekursif memeriksa superview dari touch.view untuk menemukan potensi MKAnnotationViewAnda mungkin perlu menghamparkan tampilan transparan untuk menangkap sentuhan seperti yang sering dilakukan dengan kontrol berbasis UIWebView. Tampilan Peta sudah melakukan banyak hal khusus dengan satu sentuhan untuk memungkinkan peta dipindahkan, dipusatkan, diperbesar, dll ... sehingga pesan tidak meluap ke aplikasi Anda.
Dua opsi (UNTESTED) lainnya yang dapat saya pikirkan:
1) Mundur responden pertama melalui IB dan setel ke "Pemilik File" untuk memungkinkan Pemilik file untuk menanggapi sentuhan. Saya meragukan bahwa ini akan berhasil karena MKMapView memperluas NSObject, bukan UIView dan akibatnya peristiwa sentuh masih mungkin tidak disebarluaskan kepada Anda.
2) Jika Anda ingin menjebak saat status Peta berubah (seperti pada zoom) cukup terapkan protokol MKMapViewDelegate untuk mendengarkan kejadian tertentu. Firasat saya adalah ini adalah bidikan terbaik Anda dalam menjebak beberapa interaksi dengan mudah (singkatnya menerapkan Tampilan transparan di atas Peta). Jangan lupa untuk mengatur View Controller yang menampung MKMapView sebagai delegasi peta (
map.delegate = self
).Semoga berhasil.
sumber
Saya belum bereksperimen, tetapi ada kemungkinan besar MapKit berbasis di sekitar cluster kelas, dan oleh karena itu subclassing itu sulit dan tidak efektif.
Saya menyarankan membuat tampilan MapKit subview dari tampilan kustom, yang akan memungkinkan Anda untuk mencegat kejadian sentuh sebelum mereka mencapainya.
sumber
Jadi setelah setengah hari mengotak-atik ini, saya menemukan yang berikut:
Dalam video iPhone Stanford, seorang pria dari Apple mengatakan bahwa banyak hal UIKit akan menyebabkan banyak kesalahan jika Anda "mentransfer" permintaan sentuh (alias dua metode yang dijelaskan di atas), dan Anda mungkin tidak akan membuatnya berfungsi.
SOLUSI : dijelaskan di sini: Mencegah / Membajak Peristiwa Sentuh iPhone untuk MKMapView . Pada dasarnya Anda "menangkap" kejadian tersebut sebelum responden mana pun mendapatkannya, dan menafsirkannya di sana.
sumber
Di Swift 3.0
sumber
Jadikan MKMapView sebagai subview dari tampilan kustom dan implementasikan
di tampilan kustom untuk menampilkan diri sendiri, bukan subview.
sumber
Terima kasih untuk pizza dan teriakannya - Anda menghemat banyak waktu saya.
multipletouchenabled akan bekerja secara sporadis.
Pada akhirnya, saya mengalihkan pandangan ketika saya perlu menangkap sentuhan (titik waktu yang berbeda daripada membutuhkan pinchzooms):
sumber
Saya perhatikan bahwa Anda dapat melacak jumlah dan lokasi sentuhan, dan mendapatkan lokasi masing-masing dalam tampilan:
Adakah orang lain yang mencoba menggunakan nilai-nilai ini untuk memperbarui tingkat zoom peta? Ini akan menjadi masalah mencatat posisi awal, dan kemudian lokasi selesai, menghitung perbedaan relatif dan memperbarui peta.
Saya bermain dengan kode dasar yang disediakan oleh Martin, dan ini sepertinya akan berhasil ...
sumber
Inilah yang saya kumpulkan, yang memungkinkan pinch zooms di simulator (belum mencoba di iPhone asli), tapi saya pikir akan baik-baik saja:
Ide utamanya adalah jika pengguna menggunakan dua jari, Anda melacak nilainya. Saya mencatat titik awal dan akhir di titik awal A dan B. Kemudian saya mencatat titik pelacakan saat ini, dan setelah selesai, saat selesai, saya dapat memanggil rutinitas untuk menghitung panjang relatif garis antara titik yang saya mulai , dan garis antara titik yang saya akhiri dengan menggunakan kalkulasi miring sederhana. Rasio di antara keduanya adalah jumlah zoom: Saya mengalikan rentang wilayah dengan jumlah itu.
Semoga bermanfaat bagi seseorang.
sumber
Saya mengambil ide tentang tampilan transparan "overlay", dari jawaban MystikSpiral, dan itu bekerja dengan sempurna untuk apa yang ingin saya capai; solusi cepat dan bersih.
Singkatnya, saya memiliki UITableViewCell kustom (dirancang dalam IB) dengan MKMapView di sisi kiri dan beberapa UILabel di kanan. Saya ingin membuat sel khusus sehingga Anda dapat menyentuhnya di mana saja dan ini akan mendorong pengontrol tampilan baru. Namun menyentuh peta tidak memberikan sentuhan 'ke atas' ke UITableViewCell sampai saya menambahkan UIView dengan ukuran yang sama seperti tampilan peta tepat di atasnya (dalam IB) dan menjadikannya latar belakang 'warna yang jelas' dalam kode ( jangan berpikir Anda dapat mengatur clearColor di IB ??):
Pikir itu mungkin membantu orang lain; tentu saja jika Anda ingin mencapai perilaku yang sama untuk sel tampilan tabel.
sumber