在我的应用程序中,我使用Apple的KMLViewer来显示我从KML文件中获得的注释。在文件KMLParser.m中,有一个实例变量placemarkDescription
,用于转换来自kml文件的Description标签下的信息to annotation subtitle.Now,在我的文件中,每个注释都以这种方式将信息存储在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.m中,我已将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>
我之所以这样做,是因为我希望将此字符串传递给webView并在其中可视化。
问题是,当kml加载时,方法获取描述信息,被称为严重时间。正好与存储在kml中的地标一样。直接传递字符串没有效果。如果我选择设置活动字幕选项( KMLParser中的annotation.subtitle = placemarkDescription
,也许我会获取用户点击的注释的字幕信息,但我不想显示此信息,因为它显示为这样
<table width="280px"><tr><td></td><td></td></tr></table><table width="280px"><tr......
顺便说一下,我不知道如何获取所选注释的字幕信息。 到目前为止,我只设法将描述信息存储在一个数组中(在KMLParser.m中完成)。但是我应该怎么处理该数组?如何知道哪个数组条目对应用户点击的注释(注释)已打开标注气泡。)
所以我不知道该怎么做。 也许我不太清楚:我想要做的是获取地标(注释)的描述信息,当用户点击地图中的注释时,点击disclosureButton应该将他重定向到显示描述信息的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 = @"<";
NSString *greaterThan = @">";
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;
}
}
在这行代码中发现错误(没有崩溃说明原因):
-(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__);
}
答案 0 :(得分:1)
目前尚不清楚您正在使用多少KMLViewer示例应用程序代码,但实现此目的的一种方法是创建自己的注释类,而不是像示例应用程序那样使用MKPointAnnotation
类。
自定义类(例如“PlacemarkAnnotation
”)应该实现MKAnnotation
协议或者是MKShape
的子类(如果您使用的是KMLViewer代码)。在自定义类中,添加placemarkDescription
属性。
当KMLViewer代码当前创建MKPointAnnotation
对象时,请改为创建PlacemarkAnnotation
并设置其placemarkDescription
属性而不是subtitle
属性。
然后在viewForAnnotation
委托方法中,将rightCalloutAccessoryView
设置为详细披露按钮。
接下来,在项目中添加一个带有UIWebView
的详细视图控制器。将placemarkDescription
属性添加到视图控制器。在viewDidLoad
方法中,在网络视图上调用loadHTMLString
并将其传递给placemarkDescription
(我认为您可以通过nil
传递baseURL
。
在地图视图的calloutAccessoryControlTapped
委托方法中,创建详细视图控制器,设置其placemarkDescription
属性并显示它:
-(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
属性,copy
比retain
更合适,它会消除警告。)
您可能已将mkShape
(和其他地方)中的KMLPlacemark
ivar的类型从MKShape
更改为其他内容。将这些类型更改回MKShape
。
接下来,_createShape
可能不是设置placemarkDescription
的最佳位置,因为为覆盖和注释调用了该方法。从该方法中删除您的更改,并将其放在point
方法中(也在KMLPlacemark
中)。请注意,您的更改可能存在一些与内存相关的问题。这是我的建议:
- (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 = @"<";
NSString *greaterThan = @">";
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;
}