关于苹果的KMLViewer地标说明和注释字幕

在我的应用程序中,我使用Apple的KMLViewer来显示从KML文件获得的注释。在文件KMLParser.m中,有一个实例variablesplacemarkDescription,用于将描述标签下的信息从kml文件转换为注释字幕。现在,我的文件每个注释都有这样存储在Description下的信息:

 <table width="280px"><tr><td></td><td></td></tr></table><table width="280px"><tr><td><b>Fitness Bulls</b>---Palester sportive. Sporti dhe koha e lire.....<a href="http://www.site.com/BIZ_DIR/810180432/Article-Fitness-Bulls.aspx" style="color:Green;" >Shikoni detajet >></a></td></tr><tr><td><a href="http://www.site.com/HartaV2/AddReview.aspx?gisDataId=8123855e-b798-40bc-ad2e-00346a931211" style="color:Green;" >Shkruani pershtypjen tuaj >> </a> <p style="float:right;">Postuar nga:<i>Import</i></p></td></tr></table> 

在KMLParser.mi中,将placemarkDescription从这个转换为:

 <html><body> <table width="280px"><tr><td></td><td></td></tr></table><table width="280px"><tr><td> <b>Fitness Bulls</b>---Palester sportive. Sporti dhe koha e lire..... <a href="http://www.site.com/BIZ_DIR/810180432/Article-Fitness-Bulls.aspx" style="color:Green;" >Shikoni detajet >></a></td></tr><tr><td> <a href="http://www.site.com/HartaV2/AddReview.aspx?gisDataId=8123855e-b798-40bc-ad2e-00346a931211" style="color:Green;" >Shkruani pershtypjen tuaj >> </a> <p style="float:right;">Postuar nga:<i>Import</i></p></td></tr></table> </body></html> 

我已经这样做了,因为我想把这个string传递给一个webView,并在其中可视化。 问题是,当加载kml的时候,这些方法会得到描述信息,被称为严重的时间。与kml中存储的地标的时间一样,所以直接传递string没有任何效果。如果我选​​择设置活动的subtitle选项annotation.subtitle = placemarkDescription KMLParser中的placemarkDescription),也许我会得到用户点击的注释的字幕信息,但我不想显示这个信息,因为它显示像这样

 <table width="280px"><tr><td></td><td></td></tr></table><table width="280px"><tr...... 

顺便说一句,我不知道如何获得选定的注释的字幕信息。 到目前为止,我只pipe理了一个数组中的描述信息(在KMLParser.m中完成)。但是我该怎么处理这个数组呢?如何知道哪个数组条目对应于用户点击的注释(注解宣传泡沫已打开)。

所以我不知道该怎么做。 也许我还没有太清楚:我想要做的是获取地标(注释)的描述信息,当用户点击地图上的注释时,点击揭示button应该将他redirect到显示描述信息的webView。

编辑代码添加:

DetailViewController.h

 #import <UIKit/UIKit.h> @interface DetailViewController : UIViewController<UIWebViewDelegate> { UIWebView *webView; UITextField *addressBar; UIActivityIndicatorView *activityIndicator; NSString *placemarkDescription; } @property (nonatomic, retain) IBOutlet UIWebView *webView; @property (nonatomic, retain) IBOutlet UITextField *addressBar; @property (nonatomic, retain) IBOutlet UIActivityIndicatorView *activityIndicator; @property (nonatomic, retain) NSString *placemarkDescription; -(IBAction) gotoAddress:(id)sender; -(IBAction) goBack:(id)sender; -(IBAction) goForward:(id)sender; @end 

DetailViewController.m

 #import "DetailViewController.h" @implementation DetailViewController @synthesize webView, addressBar, activityIndicator, placemarkDescription; - (void)viewDidLoad { [super viewDidLoad]; [webView loadHTMLString:placemarkDescription baseURL:nil]; } -(IBAction)gotoAddress:(id) sender { NSURL *url = [NSURL URLWithString:[addressBar text]]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; [webView loadRequest:requestObj]; [addressBar resignFirstResponder]; } -(IBAction) goBack:(id)sender { [webView goBack]; } -(IBAction) goForward:(id)sender { [webView goForward]; } - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { if (navigationType == UIWebViewNavigationTypeLinkClicked) { NSURL *URL = [request URL]; if ([[URL scheme] isEqualToString:@"http"]) { [addressBar setText:[URL absoluteString]]; [self gotoAddress:nil]; } return NO; } return YES; } - (void)webViewDidStartLoad:(UIWebView *)webView { [activityIndicator startAnimating]; } - (void)webViewDidFinishLoad:(UIWebView *)webView { [activityIndicator stopAnimating]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (void)dealloc { [super dealloc]; } @end 

PlacemarkAnnotation2.h

 #import <Foundation/Foundation.h> #import <MapKit/Mapkit.h> @interface PlacemarkAnnotation2 : NSObject <MKAnnotation> { CLLocationCoordinate2D coordinate; NSString * title; NSString * subtitle; NSString * placemarkDescription; } @property (nonatomic, assign) CLLocationCoordinate2D coordinate; @property (nonatomic, retain) NSString * title; @property (nonatomic, retain) NSString * subtitle; @property (nonatomic, retain) NSString * placemarkDescription; @end 

PlacemarkAnnotation2.m

 #import "PlacemarkAnnotation2.h" @implementation PlacemarkAnnotation2 @synthesize coordinate, title, subtitle, placemarkDescription; - (id) initWithCoordinate:(CLLocationCoordinate2D)coord andTitle:(NSString *)maintitle andSubtitle:(NSString *)subTitle { self.coordinate = coord; self.title = maintitle; self.subtitle = subTitle; return self; } -(NSString *) placemarkDescription { return placemarkDescription; } - (void) setPlacemarkDescription: (NSString *) pd { placemarkDescription = pd; } - (void) dealloc { [title dealloc]; [subtitle dealloc]; [placemarkDescription dealloc]; [super dealloc]; } @end 

KMLParser.M中的更改

 //KMLPoint class - (MKShape *)mapkitShape { PlacemarkAnnotation2 *annotation = [[PlacemarkAnnotation2 alloc] init]; annotation.coordinate = point; return [annotation autorelease]; } //KMLPlacemark class - (void)_createShape { if (!mkShape) { mkShape = [[geometry mapkitShape] retain]; mkShape.title = name; // Skip setting the subtitle for now because they're frequently // too verbose for viewing on in a callout in most kml files. NSString *lessThan = @"&lt;"; NSString *greaterThan = @"&gt;"; placemarkDescription = [placemarkDescription stringByReplacingOccurrencesOfString:lessThan withString:@"<"]; placemarkDescription = [placemarkDescription stringByReplacingOccurrencesOfString:greaterThan withString:@">"]; NSString *beforeBody = @"<html><body>"; NSString *afterBody = @"</body></html>"; NSString *finalContent = [[beforeBody stringByAppendingString:placemarkDescription] stringByAppendingString:afterBody]; placemarkDescription = finalContent; mkShape.placemarkDescription = placemarkDescription; } } 

在这行代码中find错误(没有崩溃描述的原因):

 -(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { NSLog(@">>> Entering %s <<<", __PRETTY_FUNCTION__); DetailViewController *dvc = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:[NSBundle mainBundle]]; PlacemarkAnnotation2 *pa = (PlacemarkAnnotation2 *)view.annotation; dvc.placemarkDescription = pa.placemarkDescription; [self presentModalViewController:dvc animated:YES]; [dvc release]; NSLog(@"<<< Leaving %s >>>", __PRETTY_FUNCTION__); } 

目前尚不清楚您正在使用多lessKMLViewer示例应用程序代码,但实现此目的的一种方法是创build自己的注释类,而不是像示例应用程序那样使用MKPointAnnotation类。

自定义类(例如“ PlacemarkAnnotation ”)应该实现MKAnnotation协议或者是MKAnnotation的子类(如果使用的是KMLViewer代码)。 在自定义类中,添加一个placemarkDescription属性。

在KMLViewer代码当前创build一个MKPointAnnotation对象的地方,改为创build一个PlacemarkAnnotation并设置它的MKPointAnnotation属性而不是subtitle属性。

然后在viewForAnnotation委托方法中,将rightCalloutAccessoryView设置为详细披露button。

接下来,在项目中添加一个UIWebView的详细视图控制器。 将一个placemarkDescription属性添加到视图控制器。 在viewDidLoad方法中,在Web视图上调用loadHTMLString并将其传递给loadHTMLString (我认为你可以通过baseURL )。

在地图视图的calloutAccessoryControlTapped委托方法中,创build详细视图控制器,设置其calloutAccessoryControlTapped属性并显示它:

 -(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { DetailViewController *dvc = [[DetailViewController alloc] init... PlacemarkAnnotation *pa = (PlacemarkAnnotation *)view.annotation; dvc.placemarkDescription = pa.placemarkDescription; [self presentModalViewController:dvc animated:YES]; [dvc release]; } 

编辑:

首先,看起来最好将MKShape作为自定义类的子类,而不是实现MKAnnotation协议。 其余的KMLViewer代码是基于这个假设。 因此,将@interface PlacemarkAnnotation2 : NSObject <MKAnnotation>更改为@interface PlacemarkAnnotation2 : MKShape 。 (顺便说一句,对于NSString属性, copyretain更合适,它将摆脱警告。)

它也看起来像你可能已经在KMLPlacemark (和其他地方)从MKShape更改为其他types的mkShape伊娃。 将这些types更改回MKShape

接下来, _createShape可能不是设置_createShape的最佳位置,因为对于叠加和注释都调用了该方法。 从该方法中删除您的更改,并将它们放在point方法中(也在KMLPlacemark )。 请注意,您的更改存在一些潜在的与内存相关的问题。 这是我的build议:

 - (void)_createShape { if (!mkShape) { mkShape = [[geometry mapkitShape] retain]; mkShape.title = name; // Skip setting the subtitle for now because they're frequently // too verbose for viewing on in a callout in most kml files. } } - (id <MKAnnotation>)point { [self _createShape]; if ([mkShape isKindOfClass:[PlacemarkAnnotation2 class]]) { if (placemarkDescription != nil) //check for nil, otherwise will crash when //passing to stringByAppendingString below { NSString *lessThan = @"&lt;"; NSString *greaterThan = @"&gt;"; placemarkDescription = [placemarkDescription stringByReplacingOccurrencesOfString:lessThan withString:@"<"]; placemarkDescription = [placemarkDescription stringByReplacingOccurrencesOfString:greaterThan withString:@">"]; NSString *beforeBody = @"<html><body>"; NSString *afterBody = @"</body></html>"; NSString *finalContent = [[beforeBody stringByAppendingString:placemarkDescription] stringByAppendingString:afterBody]; placemarkDescription = [finalContent retain]; //added retain above since finalContent is autoreleased //and we are setting the ivar manually. otherwise, //can result in EXC_BAD_ACCESS later. } PlacemarkAnnotation2 *pa2 = (PlacemarkAnnotation2 *)mkShape; pa2.placemarkDescription = placemarkDescription; return (id <MKAnnotation>)mkShape; } return nil; }