我对MKMapKit的局限性感到相当沮丧.我当前的问题与注释视图的z排序有关,特别是当它与触摸相关时.如果您接受默认的z顺序,mapkit会为您提供:
我尝试使用与Web上的以下代码类似的东西来解决#1(其设计旨在对z顺序进行一些控制)
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
for (MKAnnotationView * annView in views) {
TopBottomAnnotation * ann = (TopBottomAnnotation *) [annView annotation];
if ([ann top]) {
[[annView superview] bringSubviewToFront:annView];
} else {
[[annView superview] sendSubviewToBack:annView];
}
}
}
运行传递给mapView的注释视图:didAddAnnotationViews:并调整它们的z顺序确实似乎修复了#1.问题是现在标注视图不再总是位于注释视图的顶部.MapKit似乎对图层感到非常困惑(应在所有注释视图上方的图层中绘制标注).我甚至可以弄清楚它是如何混淆的,因为你收到的所有MKAnnotationViews都有相同的superview(私有类MKOverlayView).您会认为任何合理的设计都会绘制有关此叠加视图的标注.
有没有人成功解决了#1或#2?
我扩展了MapKit使用以下代码绘制自定义注释图像的能力:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
NSLog(@"Drawing a cloud on the map");
MKAnnotationView *view;
if(annotation != mapView.userLocation){
view=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"parkingloc"];
view.image=[UIImage imageNamed:@"placemarkCloud.png"];
[view setCanShowCallout:YES];
[view setRightCalloutAccessoryView:[UIButton buttonWithType:UIButtonTypeDetailDisclosure]];
}
else{
view=
}
return view;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我应该如何制作视图=以保留iPhone的内置蓝点.您可以看到我删除了为点绘制的自定义图像,但我不知道如何将其显示为默认值.
在iOS 4之前,我曾经为每个添加一个观察者MKAnnotationView添加到地图视图中,监听它的选择方法,所以我知道用户何时点击了一个引脚.
这适用于iOS 4.2.我注意到在发布时注意到注释视图实际上正在被重用,并且它在某种程度上与观察者混淆.
所以我想我可以-mapview:didSelectAnnotationView:根据MKMapViewDelegate我的需要使用该方法,但这只是添加到iOS 4.0 SDK中.
因此,为了保持兼容性,我想在我的委托上实现这个方法,并有条件地检查MKMapViewDelegate协议上是否存在此方法,这样如果它不存在,我会将我的观察者添加到注释视图中.
我怎样才能为协议方法执行此操作,类似于我们如何检查类是否为零?
更新:
正如Daniel Dickison指出的那样,我无法使用respondsToSelector:,因为我的代表已经-mapview:didSelectAnnotationView:实现了4.0+设备.我需要的是检查该设备上的协议是否具有可选-mapview:didSelectAnnotationView:方法或是否MKMapView将在其委托上查找该方法.
我最终对当前运行的iOS版本进行了测试.如果它高于4.0,MKMapView将查找该方法并调用它.
if ([[[UIDevice currentDevice] systemVersion] doubleValue] < 4.0)
[self setupObserver];
Run Code Online (Sandbox Code Playgroud)
这解决了原始问题,但以某种方式检查方法的实际协议仍然很有趣.
我的问题实际上看起来很傻......我正在编写一个使用MKMapKit的iPhone应用程序.该应用程序从提供的地理标记照片中获取EXIF元数据.问题是我检索的纬度和经度坐标,例如:
Lat:34.25733333333334
Lon:118.5373333333333
返回中国的一个位置.是否存在我缺少的区域设置,或者在使用它们之前是否需要转换纬度/经度坐标?
提前感谢您提供任何帮助.
这是我用来获取GPS数据的代码.您会注意到我正在将所有内容记录到控制台,以便我可以看到值是什么:
void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *) = ^(ALAsset *asset)
{
NSDictionary *metadata = asset.defaultRepresentation.metadata;
NSLog(@"Image Meta Data: %@",metadata);
NSDictionary *gpsdata = [metadata objectForKey:@"{GPS}"];
self.lat = [gpsdata valueForKey:@"Latitude"];
self.lng = [gpsdata valueForKey:@"Longitude"];
NSLog(@"\nLatitude: %@\nLongitude: %@",self.lat,self.lng);
};
NSURL *assetURL = [mediaInfo objectForKey:UIImagePickerControllerReferenceURL];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:assetURL
resultBlock:ALAssetsLibraryAssetForURLResultBlock
failureBlock:^(NSError *error) {
}];
UIImage *img = [mediaInfo objectForKey:@"UIImagePickerControllerEditedImage"];
previewImage.image = nil;
self.previewImage.image = img;
NSData *imageData = UIImagePNGRepresentation(img);
if ([imageData length] > 0) {
self._havePictureData = YES; …Run Code Online (Sandbox Code Playgroud) 我可以使用下面的代码(无论如何它的一部分)在两点之间创建一条线,我怎样才能使线条点缀而不是实线?也可以在线条越长的时候改变不透明度?
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
MKPolylineRenderer *renderer =[[MKPolylineRenderer alloc] initWithPolyline:overlay];
renderer.strokeColor = [UIColor orangeColor];
renderer.lineWidth = 3.0;
return renderer;
}
Run Code Online (Sandbox Code Playgroud) 我正在一个搜索地址的应用程序中实现自动完成(每个新角色添加一个搜索),我不断获取MKErrorDomain error 3,这是MKErrorLoadingThrottled.根据Apple dev的说法,这个错误发生在
未加载数据,因为数据限制有效.如果应用程序在短时间内频繁请求数据,则会发生此错误.
我确切地知道有多少请求正在进行,一个用于搜索查询中的每个新charachter(就像您希望自动完成工作一样).当然,我是一个快速的人,但只有10或15个请求后能够达到极限似乎是荒谬的.看看以下两个源代码引用,我不明白为什么我一直受到限制.
根据Apple开发:
每个应用程序或开发人员ID没有请求限制,因此编写良好的正确应用程序应该不会遇到任何问题.但是,在创建大量请求的应用程序写得不好的情况下,可能会出现限制.
正如詹姆斯霍华德在WWDC上所说:
我想谈的另一件事就是这个API的使用限制.因此,我很高兴地宣布,没有应用程序或开发人员标识符的广泛使用限制.所以,如果你的应用程序拥有大量用户并且你想要做很多请求,那就没问题了.
它会工作的.
我们所拥有的限制实际上只是防范错误应用程序的第一道防线.因此,如果您将路线请求或本地搜索请求置于无限循环中,您就会遇到错误,最终您将受到限制.
但是,如果你做了一些合理的事情,你会说哦,我只会做一些回应用户输入的指示,你知道你可以做一些,因为我们向他们展示了这个例子.
就像我们针对一个用户输入做了两个方向请求一样,这很好.但是,你知道如果你每次用户点击屏幕时你都做了10,000,那么你就会受到限制.但是,只要保持合理,你就没事了.
任何想法为什么会发生这种情况?
我在我的iOS应用程序中使用MKMapView.在我看来,我有搜索栏.如果我在地图上搜索位置,我会在搜索到的位置上添加注释.现在的问题是,我想回到我现在的位置.我见过谷歌地图应用程序,他们在地图上有一个按钮,可以将用户发送到当前位置.
如何显示该按钮?以及如何获得该按钮的点击事件?
我正在尝试在地图上的叠加层上添加模糊效果.我实际上需要在地图上的圆圈上模糊效果,我用来获得它的方法并不重要.
我有一个扩展的类,MKCircleRenderer我想在它覆盖的地图上添加模糊效果.
我正在尝试使用这种-fillPath:inContext:方法,但我对Core Graphics和Core Image的无知导致我无处可去,我真的对这个问题感到很遗憾.
我的尝试是使用CIFilter和为此我需要一个CIImage我试图从上下文创建.但是我发现没有办法创造CGBitmapContext,CGImage也不是从上下文的任何其他类.我试过的任何方法都会产生NULL而没有关于原因的进一步细节.我不记得所有我尝试过的所以我很抱歉没有指出任何相关的内容.
我的类目前实现了一个做得不多的方法:
- (instancetype)initWithOverlay:(id<MKOverlay>)overlay {
if (self = [super initWithOverlay:overlay]) {
self.strokeColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1];
self.fillColor = [UIColor colorWithRed:0.4 green:0.2 blue:0.2 alpha:0.1];
self.lineWidth = 1;
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用自定义,MKAnnotation并在视图上添加模糊效果UIVisualEffectView.这种方法的难点在于缩放时增大/减小尺寸.
这应该适用于iOS 8+
编辑
在这种情况下,圆圈内部的地图应该模糊

我正在尝试子类化MKPolyline并MKGeodesicPolyline存储他们自己的颜色(通过让子类实例返回自己的颜色MKPolylineRenderer).它工作正常MKPolyline,但我的MKGeodesicPolyline子类的实例不是子类 - 只是MKGeodesicPolylines.有谁能解释为什么?这是我的代码......
protocol MapLineProtocol: MKOverlay {
var width: CGFloat { get set }
var colour: UIColor { get set }
}
extension MapLineProtocol {
var renderer: MKPolylineRenderer {
let polylineRenderer = MKPolylineRenderer(overlay: self)
polylineRenderer.strokeColor = self.colour
polylineRenderer.lineWidth = self.width
return polylineRenderer
}
}
class MapLine: MKPolyline, MapLineProtocol {
var width: CGFloat = 3
var colour: UIColor = .blue
convenience init(start: CLLocationCoordinate2D, end: CLLocationCoordinate2D) {
let line …Run Code Online (Sandbox Code Playgroud) - 更新了新发现 - 在模拟器和设备上进行了测试.从冷启动运行应用程序时,无法正确加载地图.瓷砖没有显示.
mapViewDidFinishLoadingMap没有被召唤.因此,地图不能完成会出错,但我没有错误.
如果我只是简单地退出应用程序然后再次进入,地图就可以正常加载.这意味着如果从后台打开应用程序,则会加载地图.
有什么想法有什么变化吗?在iOS 10中工作得很好.
更新
在iOS 11 mapViewWillStartLocatingUser中被调用但不是mapViewWillStartRenderingMap.我想知道是否必须手动调用某些内容才能启动地图渲染.在iOS 9中(我测试的是什么,并且它运行得很好)mapViewWillStartRenderingMap之前被调用过mapViewWillStartLocatingUser
mapkit ×10
ios ×7
iphone ×4
mkmapview ×2
objective-c ×2
cocoa ×1
cocoa-touch ×1
core-image ×1
ios11 ×1
mkpolyline ×1
swift ×1