我有一张3D地图,里面有许多不同形状的建筑物。我希望用户点击地图上的建筑物,这将充当新视图的segue。
我计划通过创建与建筑物形状相同的隐形按钮,然后将它们放置在图像视图的顶部(用于保存地图)来实现此目的。
在做了一些阅读之后,我发现它并不像我想的那样简单地创建自定义按钮(我认为我将不得不做很多次级和定制,当我有50+以上时这似乎不合理不同形状的按钮,所以我想知道是否有另一种方法我可以用来解决这个问题。
编辑:我现在应该添加所有功能,但是我必须使用默认的矩形按钮,alpha设置为0.1。
答案 0 :(得分:3)
已编辑改进DATAMODEL
要做到这一点,你将在后台拥有一张带有地图图像的UIView。您可以使用UIImageView或在drawRect中自己渲染图像来完成此操作。
然后,您将定义多个CGPath引用。通过做这样的事情为每个建筑物建造一个...... How to create CGPathRef from Array of points每个建筑物的角落都是点。
现在以某种方式将这些路径存储在数组中。每个“可点击”都需要一条路径 建筑物。
我会将路径存储在Building对象中......
@interface Building : NSObject
@property (nonatomic) CGPath path;
@end
现在在UIView子类中重写- (void)touchesBegan...
。然后,您可以获取触摸点并遍历您的路径以找到触摸的那个...
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
for (Building *building in self.buildings) {
if (CGPathContainsPoint(building.path, CGAffineTransformIdentity, touchPoint, YES)) {
//the touch was inside this building!
//now do something with this knowledge.
}
}
}
答案 1 :(得分:1)
我曾经实施过一个meteo应用程序。
我们做了一个地图 - 有几个可点击的区域。
定义这些非矩形区域的最简单方法是将它们定义为UIBezierPath
,并使用UITapGestureRecognizer
UIBezierPath使用CGPath,但它是纯Objective-C。
在CGPath上的其他优点是,您可以轻松填充/描边这些路径 - 使用随机颜色 - 在调试时可以很好地看到它们
所以
//in you .h, or in class extension
//an array of UIBezierPath you create
// each bezierPath represent an area.
@property (nonatomic, strong) NSArray *myShapes;
//in your .m
- (void)viewDidLoad
{
[super viewDidLoad];
//load stuff
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self.view addGesture:tap];
// ...
}
- (void)handleTap:(UITapGestureRecognizer *)tap
{
UIBezierPath *recognizedArea = nil;
//if your shapes are defined in self.view coordinates :
CGPoint hitPoint = [tap locationInView:self.view];
for(UIBezierPath *regionPath in self.myShapes){
if([regionPath containsPoint:tap]){
recognizedArea = regionPath;
break;
}
}
//handle touch for THIS specific area when recognizedArea isn't nil
if(recognizedArea){
//YOUR CODE HERE
}
// you might also iterate with a normal integer increment
// and use the path index to retrieve region-specific-data from another array
}