我正在为iPhone构建基于MapKit的应用程序。
我在地图上添加了许多MKPolylines。
但是,我想让我自己的Model类符合添加到地图的MKOverlay协议,而不是拥有MKPolyline,这样我就可以在mapView中创建相应的视图时访问模型属性:viewForOverlay。
问题是我找不到从MKPolyline继承的方法,因为它没有我可以从子类'init调用的任何init方法。您只能使用便捷方法创建它们。
如何将模型属性和MKPolyline行为结合在一起?
答案 0 :(得分:7)
MANIAK_dobrii的代码是要走的路,但我发现我必须实现一些额外的MKMultiPoint方法才能使它工作,这里是我使用的AnchorLine类的完整标题和实现文件: -
标题AnchorLine.h
#import <MapKit/MapKit.h>
@interface AnchorLine : NSObject <MKOverlay> {
MKPolyline* polyline;
}
@property (nonatomic, retain) MKPolyline* polyline;
+ (AnchorLine*)initWithPolyline: (MKPolyline*) line;
@end
实施AnchorLine.m
#import "AnchorLine.h"
@implementation AnchorLine
@synthesize polyline;
+ (AnchorLine*)initWithPolyline: (MKPolyline*) line {
AnchorLine* anchorLine = [[AnchorLine alloc] init];
anchorLine.polyline = line;
return [anchorLine autorelease];
}
- (void) dealloc {
[polyline release];
polyline = nil;
[super dealloc];
}
#pragma mark MKOverlay
//@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (CLLocationCoordinate2D) coordinate {
return [polyline coordinate];
}
//@property (nonatomic, readonly) MKMapRect boundingMapRect;
- (MKMapRect) boundingMapRect {
return [polyline boundingMapRect];
}
- (BOOL)intersectsMapRect:(MKMapRect)mapRect {
return [polyline intersectsMapRect:mapRect];
}
- (MKMapPoint *) points {
return [polyline points];
}
-(NSUInteger) pointCount {
return [polyline pointCount];
}
- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range {
return [polyline getCoordinates:coords range:range];
}
@end
希望能有所帮助。
答案 1 :(得分:4)
你可以set an associated object attribute上课。这允许您将实例变量绑定到现有类。确保你自己清理干净。
答案 2 :(得分:2)
MKPolyline确实没有自己的init方法。事实上,MKPolyline的继承链中唯一具有init方法的类是NSObject。
所以当我将MKPolyline子类化时,我只是覆盖了NSObject定义的init方法......
-(id) init {
self = [super init];
if(self) {
//my initialization here
}
return self;
}
然后,当你想用坐标实例化你的子类时,你可能会做这样的事情......
-MyPolyline* myPolyline = (MyPolyline*)[MyPolyline polylineWithCoordinates:coordinates count:coordinateCount];
答案 3 :(得分:2)
更新:还有另一个选项(可能更好)为此使用邮件转发(如-forwardingTargetForSelector
或其他内容)。
我今天遇到了同样的问题,但提出了其他解决方案。我没有使用Wayne关联的对象属性建议,而是将MKPolyline
封装在另一个类中,并将MKOverlay
协议的消息传递给它。
所以我有类似于.h:
的东西@interface MyOverlay : NSObject <MKOverlay>
{
MKPolyline* polyline;
id object;
}
@property (nonatomic, retain) id object;
@property (nonatomic, retain) MKPolyline* polyline;
+ (MyOverlay*)myOverlayWithObject: (id)anObject;
@end
在.m:
@implementation MyOverlay
@synthesize object;
@synthesize polyline;
+ (MyOverlay*)routePartOverlayWithObject: (id)anObject {
MyOverlay* myOverlay = [[MyOverlay alloc] init];
... generating MKPolyline ...
myOverlay.polyline = ... generated polyline ...;
routePartOverlay.object = anObject;
return [myOverlay autorelease];
}
- (void) dealloc {
[cdRoutePart release]; cdRoutePart = nil;
[polyline release]; polyline = nil;
[super dealloc];
}
#pragma mark MKOverlay
//@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (CLLocationCoordinate2D) coordinate {
return [polyline coordinate];
}
//@property (nonatomic, readonly) MKMapRect boundingMapRect;
- (MKMapRect) boundingMapRect {
return [polyline boundingMapRect];
}
- (BOOL)intersectsMapRect:(MKMapRect)mapRect {
return [polyline intersectsMapRect:mapRect];
}
@end
所以MyOverlay
的行为类似于MKPolyline
(符合MKOverlay
),同时我可以使用它做任何事情,拥有尽可能多的属性。
答案 4 :(得分:0)
到目前为止,这里提到的内容对我来说并不是很有用,但我根据其他答案和一些独立研究设定了解决方案。我不是100%肯定的,但如果你使用在内部调用正确'init'方法的静态方法调用,你可以将MKPolyline转换为自定义子类 。
(CustomPolyline*)[CustomPolyline polylineWithCoordinates:coordinates count:coordinateCount]
上述操作无效,因为polylineWithCoordinates
仅为MKPolyline
对象而不是CustomPolyline
分配内存。我怀疑内部发生的事情是polylineWithCoordinates
以类似于[MKPolyline otherInitMethod:...]
的方式调用另一个初始化方法。并且它没有分配适当的内存量,因为它现在使用MKPolyline
静态方法调用而不是我们的CustomPolyline
静态调用。
但是如果我们使用
(CustomPolyline*)[CustomPolyline polylineWithPoints:polyline.points count:polyline.pointCount];
确实有效。我认为这是因为polylineWithPoints
使用的初始值设定项返回id
而不仅仅是链接到另一个方法调用。由于我们使用CustomPolyline
类调用它,因此初始化程序为CustomPolyline
而不是MKPolyline
分配内存。
我为什么会这样做完全错了。但我已经测试了这个,似乎工作正常。 MKPolygon
可以以类似的方式扩展。在这种情况下,我认为使用正确的静态方法是MKPolygon polygonWithCoordinates:points count:pointSet.count]]
我的实施参考:
CustomPolyline.h
#import <MapKit/MapKit.h>
typedef enum {
CustomPolylineTypeNone = 0,
CustomPolylineDifferentStrokes
} CustomPolylineType;
/**
* CustomPolyline wraps MKPolyline with additional information about a polyline useful for differentiation.
*/
@interface CustomPolyline : MKPolyline
@property CustomPolylineType type;
-(CustomPolyline*)initWithMKPolyline:(MKPolyline*)polyline;
@end
CustomPolyline.m
#import "CustomPolyline.h"
@implementation CustomPolyline
@synthesize type;
/**
* Takes an MKPolyline and uses its attributes to create a new CustomPolyline
*/
-(CustomPolyline*)initWithMKPolyline:(MKPolyline*)polyline
{
// We must use the this specific class function in this manner to generate an actual
// CustomPolyline object as opposed to a MKPolyline by a different name
return (CustomPolyline*)[CustomPolyline polylineWithPoints:polyline.points count:polyline.pointCount];
}
@end