2013-03-08 28 views
40

Tôi có một danh sách các chú thích (MKPointAnnotation). Tôi có một UIViewController cho toàn bộ khung nhìn, MKMapView triển khai Controller, mà tôi nghĩ là hữu ích cho việc phát hiện tương tác người dùng với bản đồ, bộ điều khiển MKPointAnnotation của riêng tôi (subclass) Controller cho biết cách hiển thị chú thích.MKMapView MKPointAnnotation tap event

Tuy nhiên, tôi bị tấn công khi phát hiện sự kiện nhấn của người dùng.

Googling nói với tôi rằng tôi phải làm điều gì đó bằng cách thực hiện chức năng sau.

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 

và cũng phải thực hiện điều này trong một số lớp thực hiện MapViewDelegate (Giao thức).

Nhưng tôi hoàn toàn bối rối và không thể tiến lên phía trước. Bất cứ ai có thể cho tôi biết nơi để làm gì?

Xin lỗi vì tất cả những phiền phức!

+0

bạn phải thiết lập các thẻ cho mỗi chú thích, vì vậy đó khi bạn nhấn bất kỳ chú thích bạn có thể nhận được thẻ trở lại từ chú thích và gọi các thành viên dữ liệu tương ứng của mảng tạo ra các chú thích này. – yunas

+0

- (void) mapView: (MKMapView *) chú thích mapViewXem: (MKAnnotationView *) xem calloutAccessoryControlTapped: (UIControl *) kiểm soát { NSLog (@ "đã ở đây"); } ..... Tôi đặt chức năng này trong cả ba bộ điều khiển nhưng không ai trong số chúng đang được gọi .... bạn có thể cho tôi biết tôi nên xác định chức năng này ở đâu? –

Trả lời

95

Có hai cách phát hiện tương tác người dùng với quan điểm chú thích của mình. Kỹ thuật phổ biến là xác định chú dẫn (bong bóng popover nhỏ tiêu chuẩn mà bạn thấy khi bạn nhấn vào một ghim trong ứng dụng bản đồ điển hình) cho số MKAnnotationView của bạn. Và bạn tạo cái nhìn chú thích cho chú thích của mình trong các tiêu chuẩn viewForAnnotation phương pháp:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{ 
    if ([annotation isKindOfClass:[MKUserLocation class]]) 
     return nil; 

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"]; 
    annotationView.canShowCallout = YES; 
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 

    return annotationView; 
} 

Bằng cách này, bạn nhận được một lời thoại, nhưng bạn đang thêm một phụ kiện đúng, đó là, trong ví dụ của tôi ở trên, một tiết lộ chỉ báo. Theo cách đó, họ chạm vào chế độ xem chú thích của bạn (ví dụ ở trên, ghim trên bản đồ), họ thấy chú thích và khi họ chạm vào phụ kiện phù hợp của chú thích đó (chỉ báo tiết lộ nhỏ trong ví dụ này), số calloutAccessoryControlTapped của bạn được gọi (trong ví dụ dưới đây của tôi, thực hiện một segue cho một số bộ điều khiển xem chi tiết):

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 
{ 
    [self performSegueWithIdentifier:@"DetailsIphone" sender:view]; 
} 

Đó là một trải nghiệm người dùng rất điển hình trên màn hình iPhone nhỏ. Tuy nhiên, nếu bạn không thích UX đó và bạn không muốn chú thích chuẩn, nhưng thay vào đó bạn muốn điều gì đó khác xảy ra, bạn có thể xác định MKAnnotationView để chú thích không hiển thị, nhưng thay vào đó bạn chặn nó và làm một cái gì đó khác (ví dụ, trên các ứng dụng bản đồ iPad, bạn có thể hiển thị một số popover phức tạp hơn là chú thích chuẩn). Ví dụ, bạn có thể có MKAnnotationView của bạn không hiển thị một chú thích:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{ 
    if ([annotation isKindOfClass:[MKUserLocation class]]) 
     return nil; 

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"]; 
    annotationView.canShowCallout = NO; 

    return annotationView; 
} 

Nhưng sau đó bạn có thể tự xử lý didSelectAnnotationView để phát hiện khi người dùng khai thác trên MKAnnotationView của bạn, trong ví dụ này cho thấy một popover:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view 
{ 
    [mapView deselectAnnotation:view.annotation animated:YES]; 

    DetailsViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsPopover"]; 
    controller.annotation = view.annotation; 
    self.popover = [[UIPopoverController alloc] initWithContentViewController:controller]; 
    self.popover.delegate = self; 
    [self.popover presentPopoverFromRect:view.frame 
            inView:view.superview 
       permittedArrowDirections:UIPopoverArrowDirectionAny 
           animated:YES]; 
} 

Tôi bao gồm một số ảnh chụp nhanh màn hình cho giao diện người dùng được cung cấp bởi mã ở trên trong my answer here.

+0

Xin chào, Điều này dường như không hoạt động đối với iOS7 trở lên. Mọi đề xuất sửa lỗi cho iOS8? – roshi

+0

@roshi Tôi đã thử nghiệm nó và điều này hoạt động tốt trong iOS 8. Bạn có đặt đại biểu của chế độ xem bản đồ của mình không? Nếu bạn vẫn gặp sự cố, có thể đăng câu hỏi của riêng bạn lên S.O. với các mẫu mã chi tiết, mô tả về những gì bạn đã thử, v.v. – Rob

+0

@Rob Bạn có thể xem http://stackoverflow.com/questions/30396754/ios-custom-annotation-a-view-below-the không -khi-pin & giúp tôi giải quyết vấn đề của tôi – iYoung

3

Thêm nút trong phương pháp này

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
{ 
    pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
    pinView.canShowCallout = YES; 
} 

Then callout method 
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 
{ 
     InfoView *infoView = [[InfoView alloc]initWithNibName:@"InfoView" bundle:nil]; 
     [self.navigationController pushViewController:infoView animated:YES]; 

} 
+0

Bạn có thể cho tôi biết nơi nào tôi nên triển khai chúng? Bộ điều khiển MKMapView? –

+0

@RaviVooda yaa Được áp dụng cho việc mã hóa MapViewpart. bất kỳ vấn đề nào khác mà bạn có thể hỏi tôi :) – Bajaj

+0

@RaviVooda Bạn nên thực hiện những điều này trong 'delegate' cho' MKMapView' của bạn. Bạn thường chỉ định 'delegate' cho' MKMapView' để xem bộ điều khiển cho khung nhìn có chế độ xem bản đồ trên nó. Nhưng đừng quên đặt đại biểu của chế độ xem bản đồ (trong mã hoặc qua Trình tạo giao diện). – Rob

4

cướp ví dụ cho Swift 3:

class MapViewController: UIViewController 
{ 
    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     // Create map view in storyboard 
     view.delegate = self 
    } 
} 

extension MapViewController: MKMapViewDelegate 
{ 
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? 
    { 
     let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotationView") 
     annotationView.canShowCallout = true 
     annotationView.rightCalloutAccessoryView = UIButton.init(type: UIButtonType.detailDisclosure) 

     return annotationView 
    } 

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) 
    { 
     guard let annotation = view.annotation else 
     { 
      return 
     } 

     let urlString = "http://maps.apple.com/?sll=\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)" 
     guard let url = URL(string: urlString) else 
     { 
      return 
     } 

     UIApplication.shared.openURL(url) 
    } 
}