2013-02-12 105 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 

}