Saya sedang mengerjakan mapkit dan terjebak.
Saya memiliki tampilan anotasi khusus yang saya gunakan, dan saya ingin menggunakan properti gambar untuk menampilkan titik pada peta dengan ikon saya sendiri. Saya memiliki ini bekerja dengan baik. Tapi yang juga ingin saya lakukan adalah mengganti tampilan info default (gelembung yang muncul dengan judul / subjudul saat ikon anotasi disentuh). Saya ingin dapat mengontrol info itu sendiri: mapkit hanya menyediakan akses ke tampilan info tambahan kiri dan kanan, tetapi tidak ada cara untuk memberikan tampilan kustom untuk gelembung info, atau memberinya ukuran nol, atau apa pun.
Ide saya adalah menimpa selectAnnotation / deselectAnnotation di my MKMapViewDelegate
, dan kemudian menggambar tampilan kustom saya sendiri dengan melakukan panggilan ke tampilan anotasi kustom saya. Ini berfungsi, tetapi hanya jika canShowCallout
disetel ke YES
dalam kelas tampilan anotasi kustom saya. Metode ini TIDAK dipanggil jika saya menyetelnya ke NO
(yang saya inginkan, sehingga gelembung info default tidak digambar). Jadi saya tidak tahu apakah pengguna menyentuh titik saya di peta (memilihnya) atau menyentuh titik yang bukan bagian dari tampilan anotasi saya (menghapusnya) tanpa memunculkan tampilan gelembung info default.
Saya mencoba melalui jalur yang berbeda dan hanya menangani sendiri semua kejadian sentuh di peta, dan sepertinya saya tidak dapat melakukannya. Saya membaca pos lain yang terkait dengan menangkap peristiwa sentuh di tampilan peta, tetapi itu tidak persis seperti yang saya inginkan. Adakah cara untuk menggali tampilan peta untuk menghilangkan gelembung info sebelum menggambar? Saya bingung.
Ada saran? Apakah saya melewatkan sesuatu yang jelas?
Jawaban:
Ada solusi yang lebih mudah.
Buat kustom
UIView
(untuk info Anda).Kemudian buat subkelas
MKAnnotationView
dan timpasetSelected
sebagai berikut:- (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; if(selected) { //Add your custom view to self... } else { //Remove your custom view... } }
Boom, pekerjaan selesai.
sumber
detailCalloutAccessoryView
Di masa lalu ini menyebalkan , tetapi Apple telah menyelesaikannya, cukup periksa dokumen di MKAnnotationView
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) view.canShowCallout = true view.detailCalloutAccessoryView = UIImageView(image: UIImage(named: "zebra"))
Sungguh, itu dia. Membawa UIView apapun.
sumber
Melanjutkan dari jawaban @ TappCandy yang sangat sederhana, jika Anda ingin menganimasikan gelembung Anda dengan cara yang sama seperti yang default, saya telah membuat metode animasi ini:
- (void)animateIn { float myBubbleWidth = 247; float myBubbleHeight = 59; calloutView.frame = CGRectMake(-myBubbleWidth*0.005+8, -myBubbleHeight*0.01-2, myBubbleWidth*0.01, myBubbleHeight*0.01); [self addSubview:calloutView]; [UIView animateWithDuration:0.12 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^(void) { calloutView.frame = CGRectMake(-myBubbleWidth*0.55+8, -myBubbleHeight*1.1-2, myBubbleWidth*1.1, myBubbleHeight*1.1); } completion:^(BOOL finished) { [UIView animateWithDuration:0.1 animations:^(void) { calloutView.frame = CGRectMake(-myBubbleWidth*0.475+8, -myBubbleHeight*0.95-2, myBubbleWidth*0.95, myBubbleHeight*0.95); } completion:^(BOOL finished) { [UIView animateWithDuration:0.075 animations:^(void) { calloutView.frame = CGRectMake(-round(myBubbleWidth/2-8), -myBubbleHeight-2, myBubbleWidth, myBubbleHeight); }]; }]; }]; }
Kelihatannya cukup rumit, tetapi selama titik gelembung info Anda dirancang untuk menjadi tengah-bawah, Anda hanya dapat mengganti
myBubbleWidth
danmyBubbleHeight
dengan ukuran Anda sendiri agar berfungsi. Dan ingat untuk memastikanautoResizeMask
properti subview Anda telah diatur ke 63 (yaitu "semua") sehingga skalanya dengan benar di animasi.: -Joe
sumber
CABasicAnimation
... Terlalu lama untuk diingat! Saya tahu saya harus menganimasikan properti y juga, karena offset tengah.CGRectMake
?Menemukan ini sebagai solusi terbaik untuk saya. Anda harus menggunakan beberapa kreativitas untuk melakukan kustomisasi Anda sendiri
Di
MKAnnotationView
subkelas Anda, Anda dapat menggunakan- (void)didAddSubview:(UIView *)subview{ int image = 0; int labelcount = 0; if ([[[subview class] description] isEqualToString:@"UICalloutView"]) { for (UIView *subsubView in subview.subviews) { if ([subsubView class] == [UIImageView class]) { UIImageView *imageView = ((UIImageView *)subsubView); switch (image) { case 0: [imageView setImage:[UIImage imageNamed:@"map_left"]]; break; case 1: [imageView setImage:[UIImage imageNamed:@"map_right"]]; break; case 3: [imageView setImage:[UIImage imageNamed:@"map_arrow"]]; break; default: [imageView setImage:[UIImage imageNamed:@"map_mid"]]; break; } image++; }else if ([subsubView class] == [UILabel class]) { UILabel *labelView = ((UILabel *)subsubView); switch (labelcount) { case 0: labelView.textColor = [UIColor blackColor]; break; case 1: labelView.textColor = [UIColor lightGrayColor]; break; default: break; } labelView.shadowOffset = CGSizeMake(0, 0); [labelView sizeToFit]; labelcount++; } } } }
Dan jika
subview
adalah aUICalloutView
, maka Anda dapat mengacaukannya, dan apa yang ada di dalamnya.sumber
if ([[[subview class] description] isEqualToString:@"UICalloutView"])
Saya pikir ada cara yang lebih baik, tapi ini berhasil.Saya memiliki masalah yang sama. Ada banyak postingan blog tentang topik ini di blog ini http://spitzkoff.com/craig/?p=81 .
Hanya menggunakan
MKMapViewDelegate
tidak membantu Anda di sini dan subclassingMKMapView
dan mencoba untuk memperluas fungsionalitas yang ada juga tidak berhasil untuk saya.Apa yang akhirnya saya lakukan adalah membuat milik saya sendiri
CustomCalloutView
yang saya miliki di atas milik sayaMKMapView
. Anda dapat mengatur gaya tampilan ini sesuai keinginan Anda.Saya
CustomCalloutView
memiliki metode yang mirip dengan ini:- (void) openForAnnotation: (id)anAnnotation { self.annotation = anAnnotation; // remove from view [self removeFromSuperview]; titleLabel.text = self.annotation.title; [self updateSubviews]; [self updateSpeechBubble]; [self.mapView addSubview: self]; }
Dibutuhkan
MKAnnotation
objek dan menetapkan judulnya sendiri, kemudian memanggil dua metode lain yang cukup jelek yang menyesuaikan lebar dan ukuran konten callout dan kemudian menggambar gelembung ucapan di sekitarnya pada posisi yang benar.Akhirnya tampilan tersebut ditambahkan sebagai subview ke mapView. Masalah dengan solusi ini adalah sulit untuk menjaga callout pada posisi yang benar saat tampilan peta di-scroll. Saya hanya menyembunyikan callout dalam metode delegasi tampilan peta pada perubahan wilayah untuk memecahkan masalah ini.
Butuh beberapa waktu untuk menyelesaikan semua masalah itu, tetapi sekarang callout hampir berperilaku seperti yang resmi, tetapi saya memilikinya dengan gaya saya sendiri.
sumber
Pada dasarnya untuk mengatasi ini, seseorang perlu: a) Mencegah gelembung info default muncul. b) Cari tahu anotasi mana yang diklik.
Saya dapat mencapai ini dengan: a) pengaturan canShowCallout ke NO b) subclassing, MKPinAnnotationView dan menimpa metode touchesBegan dan touchesEnd.
Catatan: Anda perlu menangani kejadian sentuh untuk MKAnnotationView dan bukan MKMapView
sumber
Saya baru saja datang dengan pendekatan, idenya di sini
// Detect the touch point of the AnnotationView ( i mean the red or green pin ) // Based on that draw a UIView and add it to subview. - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated { CGPoint newPoint = [self.mapView convertCoordinate:selectedCoordinate toPointToView:self.view]; // NSLog(@"regionWillChangeAnimated newPoint %f,%f",newPoint.x,newPoint.y); [testview setCenter:CGPointMake(newPoint.x+5,newPoint.y-((testview.frame.size.height/2)+35))]; [testview setHidden:YES]; } - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { CGPoint newPoint = [self.mapView convertCoordinate:selectedCoordinate toPointToView:self.view]; // NSLog(@"regionDidChangeAnimated newPoint %f,%f",newPoint.x,newPoint.y); [testview setCenter:CGPointMake(newPoint.x,newPoint.y-((testview.frame.size.height/2)+35))]; [testview setHidden:NO]; } - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { NSLog(@"Select"); showCallout = YES; CGPoint point = [self.mapView convertPoint:view.frame.origin fromView:view.superview]; [testview setHidden:NO]; [testview setCenter:CGPointMake(point.x+5,point.y-(testview.frame.size.height/2))]; selectedCoordinate = view.annotation.coordinate; [self animateIn]; } - (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view { NSLog(@"deSelect"); if(!showCallout) { [testview setHidden:YES]; } }
Di sini - testview
UIView
berukuran 320x100 - showCallout adalah BOOL -[self animateIn];
adalah fungsi yang menampilkan animasi sepertiUIAlertView
.sumber
Anda dapat menggunakan leftCalloutView, menyetel annotation.text ke @ ""
Silakan temukan di bawah kode contoh:
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID]; if(pinView == nil){ pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease]; } CGSize sizeText = [annotation.title sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:12] constrainedToSize:CGSizeMake(150, CGRectGetHeight(pinView.frame)) lineBreakMode:UILineBreakModeTailTruncation]; pinView.canShowCallout = YES; UILabel *lblTitolo = [[UILabel alloc] initWithFrame:CGRectMake(2,2,150,sizeText.height)]; lblTitolo.text = [NSString stringWithString:ann.title]; lblTitolo.font = [UIFont fontWithName:@"HelveticaNeue" size:12]; lblTitolo.lineBreakMode = UILineBreakModeTailTruncation; lblTitolo.numberOfLines = 0; pinView.leftCalloutAccessoryView = lblTitolo; [lblTitolo release]; annotation.title = @" ";
sumber
Saya telah mendorong garpu saya dari SMCalloutView yang sangat baik yang memecahkan masalah dengan menyediakan tampilan khusus untuk info dan memungkinkan lebar / tinggi yang fleksibel tanpa rasa sakit. Masih ada beberapa keanehan untuk dikerjakan, tetapi sejauh ini cukup berfungsi:
https://github.com/u10int/calloutview
sumber