繁体   English   中英

非矩形“可点击”区域

[英]Non-rectangular 'clickable' area

我有一个3D地图,有许多不同形状的建筑物。 我希望用户点击地图上的建筑物,这将充当新视图的segue。

我计划通过创建与建筑物相同形状的隐形按钮,然后将它们放置在图像视图(保存地图)的顶部来实现此目的。

在做了一些阅读之后,我发现它并不像我想的那样简单地创建自定义按钮(我认为我将不得不做很多次级和定制,当我有50多个不同形状的按钮时这似乎不合理我想知道是否还有另一种方法可以用来解决这个问题。


编辑:我现在应该添加所有功能,但我必须使用默认矩形按钮,alpha设置为0.1。

编辑改进DATAMODEL

要做到这一点,你将在后台拥有一张带有地图图像的UIView。 您可以使用UIImageView或通过drawRect自己渲染图像来完成此操作。

然后,您将定义几个CGPath引用。 通过做这样的事情为每个建筑物一个... 如何从点数组创建CGPathRef点将是每个建筑物的角落。

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

我会将路径存储在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.
        }
    }
}

我曾经有过一次实现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

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM