2013-02-12 72 views
1

我有一张带有许多不同形状建筑物的3D地图。我希望用户点击地图上的建筑物,这将成为新景观的延续。非矩形“可点击”区域

我计划通过创建不可见按钮形状相同的建筑,然后再铺设他们在ImageView的(持有地图)的顶上去这件事。

在做了一些阅读之后,我发现它并不像我想要创建自定义按钮那么简单(我认为我将不得不做很多的sublcassing和定制,这在我有50 +不同形状的按钮),所以我想知道是否有另一种方法可以用来解决这个问题。


编辑:我想补充一点,现在,所有的功能是工作,但我不得不使用默认的矩形按钮,Alpha设置为0.1。

回答

3

编辑以IMPROVE数据模型

要做到这一点,你将不得不与背景的地图图像一个UIView。您可以使用UIImageView或通过将图像自己渲染到drawRect中来完成此操作。

然后,您将定义几个CGPath引用。每个建筑物通过做这样的事情...... How to create CGPathRef from Array of points这些点将成为每个建筑物的角落。

现在将这些路径以某种方式存储在数组中。您需要为每个“可点击”建筑物建造一条路径。

我现在的路径存储大厦对象或东西在里面......

@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. 
     } 
    } 
} 
+0

所以你说把我现在的UIImageView内一个UIView,然后只检查所有触摸的位置? – BloonsTowerDefence 2013-02-12 14:16:54

+0

对不起,没有很好解释。将编辑。\ – Fogmeister 2013-02-12 14:17:35

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 

}