- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
背景
在 iOS6 中,我过去常常在 MKMapView 上添加几个 MKPolygon
(叠加层),并为 mapView:viewForOverlay:
提供特定的 MKOverlayView
: > 回调(参见 MKMapViewDelegate Class Reference)。这个特定 View 的工作是使用 Quartz 2D 用自定义图案填充多边形。它确实工作正常。
现在,这似乎不再像我以前那样在 iOS7 上工作了。
因为 mapView:viewForOverlay:
在 iOS SDK7 以及 MKOverlayView
及其子类中被弃用,我尝试切换到 mapView:rendererForOverlay:
和子类化 MKOverlayRenderer
没有成功:遇到的问题都是一样的。
因此,以下示例代码将使用 MKOverlayView,但您可以在下面的代码中轻松地将 view/View 替换为 renderer/Renderer 并获得相同的效果。
遇到的问题
我已将问题减少到能够重现它的最小代码示例,结果如下:
在 iOS6 上(如预期的那样):
在 iOS7 上(与预期不同):
我希望我的多边形总是用相同的图案填充,并且图案的大小在屏幕上保持不变,与 map 的缩放级别无关。
唉,在 iOS7 上,当在 map 上添加多个叠加层时,在缩小多边形的某些部分时,屏幕上的图案大小会减小。只有在以最大缩放级别放大时,图案才会获得正确的尺寸。
问题没有出现:
mapView:insertOverlay:atIndex:
添加多个叠加层时)即使只添加了一个有图案的叠加层和其他无图案的叠加层,问题似乎也会发生。
代码示例
MTViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@interface MTViewController : UIViewController<MKMapViewDelegate>
@property (strong, nonatomic) IBOutlet MKMapView *mapView;
@end
MTViewController.m
#import "MTViewController.h"
#import <MapKit/MapKit.h>
#import "MTPolygonWithPatternOverlayView.h"
@implementation MTViewController
- (void)dealloc {
self.mapView.delegate = nil;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = @"MapTest - CGPattern";
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView.delegate = self;
// Add a 4 polygon overlays on the map
int count = 0;
float delta = 0.012;
for (int i = 0; i < 4; i++) {
CLLocationCoordinate2D coords[4];
coords[0] = CLLocationCoordinate2DMake(58.395,15.555 + (i*delta));
coords[1] = CLLocationCoordinate2DMake(58.390,15.560 + (i*delta));
coords[2] = CLLocationCoordinate2DMake(58.385,15.555 + (i*delta));
coords[3] = CLLocationCoordinate2DMake(58.390,15.550 + (i*delta));
MKPolygon *overlay = [MKPolygon polygonWithCoordinates:coords count:4];
[self.mapView insertOverlay:overlay atIndex:count++];
}
// Zoom to region containing polygons
MKCoordinateRegion region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(58.390,15.561), MKCoordinateSpanMake(0.015, 0.015));
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:NO];
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay {
MKOverlayView *overlayView = nil;
if ([overlay isKindOfClass:[MKPolygon class]]) {
MTPolygonWithPatternOverlayView *polygonOverlayView = [[MTPolygonWithPatternOverlayView alloc] initWithPolygon:overlay];
polygonOverlayView.alpha = 1.0f;
polygonOverlayView.strokeColor = [UIColor blueColor];
polygonOverlayView.lineWidth = 3.0f * [[UIScreen mainScreen] scale];
overlayView = polygonOverlayView;
}
return overlayView;
}
@end
MTPolygonWithPatternOverlayView.h
#import <MapKit/MapKit.h>
@interface MTPolygonWithPatternOverlayView : MKPolygonView
@end
MTPolygonWithPatternOverlayView.m
#import "MTPolygonWithPatternOverlayView.h"
@implementation MTPolygonWithPatternOverlayView
void patternReleaseInfoCallback(void *info) {
}
void drawPatternCell(void *info, CGContextRef context) {
float cellWidth = CGContextGetClipBoundingBox(context).size.width;
float cellHeight = CGContextGetClipBoundingBox(context).size.height;
// Make line width look constant on screen independently of map zoom level
CGFloat lineWidth = [[UIScreen mainScreen] scale] * cellWidth / 64.0f;
CGContextSetLineWidth(context, lineWidth);
// Draw following pattern in cell:
// \ /
// \ /
// \ _ /
// |_|
// / \
// / \
// / \
// Draw diagonal
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGPoint points [] = {{0.0,0.0}, {cellWidth,cellHeight }, {cellWidth,0.0}, {0.0,cellHeight}};
CGContextStrokeLineSegments(context, points, 4);
// Draw middle square
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
float partWidth = cellWidth / 8;
CGRect middleSpot = CGRectMake(partWidth * 3, partWidth*3, 2* partWidth, 2*partWidth);
CGContextFillRect(context, middleSpot);
}
- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context {
CGPatternCallbacks callBack;
callBack.drawPattern = &drawPatternCell;
callBack.releaseInfo = &patternReleaseInfoCallback;
callBack.version = 0;
float cellWidth = CGContextGetClipBoundingBox(context).size.width / 4;
CGPatternRef pattern = CGPatternCreate(NULL, CGRectMake(0.0f, 0.0f, cellWidth, cellWidth), CGAffineTransformIdentity, cellWidth, cellWidth, kCGPatternTilingConstantSpacing, true, &callBack);
CGContextSaveGState(context);
CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern (NULL);
CGContextSetFillColorSpace (context, patternSpace);
CGContextAddPath(context, path);
float alpha = 1;
CGContextSetFillPattern(context, pattern, &alpha);
CGContextDrawPath(context, kCGPathFill);
CGContextRestoreGState(context);
CGColorSpaceRelease (patternSpace);
CGPatternRelease(pattern);
}
@end
问题
我正准备将此作为 Apple 错误跟踪器上的错误进行报告,但我想先检查是否其他人在我使用 MapKit 和 Quartz 2D 时发现了错误。
编辑 #1: 我试图通过将 fillPath
的代码包装在公共(public)队列上的 dispatch_sync
调用中来使其线程安全但它不能解决问题。
编辑#2:在 iOS 7.0.3 中未修复
最佳答案
问题实际上是一个错误并从 iOS 7.1 解决
关于ios - 使用 CGPattern 填充 MKPolygon 时,多边形叠加相互干扰(使用 Quartz 2D),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19247927/
我知道确实有一个具体问题讨论了这一点,但它有点老了,如果可能的话,我想了解更多技术性知识。 首先看一下这个截图:https://www.dropbox.com/s/f94q3qaxrog0ec9/in
我正在尝试查找 MKPolygon 叠加层中包含的邮政编码。我知道找到包含坐标的邮政编码很简单。多边形所包含的面积怎么样? 我正在考虑的一些方法: 只需使用多边形边界线坐标中的邮政编码即可。该方法
大家好,这是一个看似简单的问题,但对我来说显然太复杂了。我正在尝试创建一个 MKPolygon 实例,但进展不太顺利。这是代码: MKMapPoint point1 = {38.53607,-121.
我在互联网上搜索过,但找不到这个问题的答案。可以在 MKPolygon 中画一个洞吗?像这样: 我记得我见过这样的东西,但我不确定它是否与iOS有关。可以这样做吗?(如果可以的话)我应该如何开始? 谢
试图弄清楚这个 MKPolygon 的工作原理。我创建了整个堆 MKMapPoints 并将它们放入一个数组中。然后我用它们制作一个多边形: [MKPolygon polygonWithPoints:
我正在我的 MKMapView 中绘制一堆 MKPolygons。其中一些彼此叠放。如何将选定的多边形置于顶部/前面? 我在从多边形层创建的 MKPolygonView 上尝试了 bringSubvi
我试图在我的 map 上创建一个形状,但我很难找到有关使用 swift 的 mkpolygon 的任何信息。我希望这里的人能看到这一点并指出我正确的方向。 这是我目前拥有的,但多边形没有出现。 fun
我第一次使用 MKPolygon 和 MKPolygonView 作为 map 叠加层。我可以在一个区域上放置一个形状,填充颜色填充多边形的内部。 我正在寻找一种方法,可以在我的 map 上除多边形内
我已经创建了一个 MKMapView,其中包含基于坐标的 MKPolygon。 map 上有多个多边形(查看 here 以了解我重新创建为应用程序的示例)。 我想要做的是,当用户触摸多边形时,它会打开
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我有一个应用程序,它允许用户绘制他们自己的地理围栏。现在它的工作方式是用户在屏幕上绘制他们的地理围栏,应用程序跟踪他们正在绘制的位置并将他们的路径存储到 CGMutablePath 中。 我的问题是如
我一直在尝试对 MKPolygon 进行计算,我已经点击了此处的几个链接并进行了相应的调整。我似乎无法正确计算平方米。如果需要,我可以提供更多信息 这是我的代码 func polygonArea()
我正在尝试使用以下代码呈现 MKPolygon: NSMutableArray *overlays = [NSMutableArray array]; for (NSDictionar
我正在开发一个带有 map 的应用程序,用户可以在其中绘制多边形区域。 我的问题是可以用节点绘制多边形(见图片)(我不知道节点是否是正确的词)。我没有找到防止多边形打结的简单方法。对于附图的情况,我希
我想知道点击是否在 MKPolygon 内。 我有一个 MKPolygon: CLLocationCoordinate2D points[4]; points[0] = CLLocationCoor
我正在尝试使用一组坐标的外边界构建 MKPolygon。 据我所知,Xcode 中没有提供实现此目的的功能(MKPolygon 方法将使用所有点来构建多边形,包括内部点)。 经过一些研究,我发现凸包可
我有一个带有多边形覆盖层的 MKMapView,我需要将其转换为 UIView。我有对 MKMapView 和 MKPolygon 的引用,但我似乎无法找到一种方法来提取 MKPolygon 的坐标并
我在应用程序中使用许多 MKPolygon 对象来在其 map View 中显示各种元素。我希望能够更灵活地控制这些对象,并希望能够针对特定方法编辑它们的 alpha。据我所知,该类没有 alpha
这里是菜鸟。我已经阅读了如何检测 MKPolygon 中的点,但我在实现它时遇到了困难 - 它可能只与代码中我正在检查用户位置的部分有关......我不是即使确定它是否持续检查。无论如何,这是相关代码
我想在使用 Mapkit 的 MKMap 上使用 MKPolygon 绘制走廊。我有一条从 A 站到 B 站的路线。 我在绘制走廊的路线周围有 MKMapRects。现在我想将所有矩形合并为一个多边形
我是一名优秀的程序员,十分优秀!