[英]Adding multiple tappable shapes to UIView
我有很多展位的平面圖。 加載UIView
時,將顯示UIImage
和平面圖,並檢查數據庫以獲取參展商及其位置的列表。 將位置加載到陣列中,並為每個參展商創建一個UIButton
,並將其放置在其展位所在的平面圖上。 點擊時,此按鈕將顯示有關該參展商的信息。
這是平面圖的屏幕截圖,其中帶有渲染按鈕的框。
這很好用,但是我需要將按鈕設置為不規則形狀(三角形,五邊形,圓形等)。 因此,我需要一種繪制這些形狀並使其與按鈕一樣可單擊的方法。
我創建了一個測試類,該類生成一個包含形狀的UIView
並將其添加到我的原始UIView
。 我感覺這可能不是正確的方法,因為我將需要在屏幕上具有許多按鈕,這意味着許多視圖相互堆疊。 我不知道如何檢查點擊的形狀,因為UIViews
會相互重疊。
是否可以在一個視圖上繪制所有形狀,然后添加視圖? 最好的方法是什么?
就UI而言,最干凈的方法是使用實際的按鈕。 將其類型設置為custom,並將其image屬性設置為要顯示的圖像。 這樣,按鈕可以正確處理突出顯示,並像常規按鈕一樣管理IBAction。 您可以將所有按鈕設置為指向相同的動作,並使用標簽值確定哪個按鈕是哪個按鈕。
您可以從代碼中或在IB中創建這些按鈕-更好地適合您的設計。
您也可以使用自定義視圖或上面帶有圖形的單個視圖來執行此操作。 如果對每個展位使用視圖,則需要在每個視圖上附加一個輕擊手勢識別器,並將其userInteractionEnabled標志設置為YES。
如果要在整個平面圖中使用圖形,則需要在圖形視圖中添加一個輕擊手勢識別器,然后解釋該輕敲的坐標以找出其所放到的圖像。
覆蓋- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
地圖表示者視圖的- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
方法的- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
方法。 因此,您將能夠將當前觸摸位置與所有形狀進行比較,並計算出您的觸摸點所處的形狀。 對於不同的形狀有不同的方法(例如,點在矩形內嗎? )
ole有一個很棒的項目: OBShapedButtons 。 他通過檢查觸摸像素的alpha值並覆蓋-pointInside:withEvent:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
// Return NO if even super returns NO (i.e., if point lies outside our bounds)
BOOL superResult = [super pointInside:point withEvent:event];
if (!superResult) {
return superResult;
}
// Don't check again if we just queried the same point
// (because pointInside:withEvent: gets often called multiple times)
if (CGPointEqualToPoint(point, self.previousTouchPoint)) {
return self.previousTouchHitTestResponse;
} else {
self.previousTouchPoint = point;
}
BOOL response = NO;
if (self.buttonImage == nil && self.buttonBackground == nil) {
response = YES;
}
else if (self.buttonImage != nil && self.buttonBackground == nil) {
response = [self isAlphaVisibleAtPoint:point forImage:self.buttonImage];
}
else if (self.buttonImage == nil && self.buttonBackground != nil) {
response = [self isAlphaVisibleAtPoint:point forImage:self.buttonBackground];
}
else {
if ([self isAlphaVisibleAtPoint:point forImage:self.buttonImage]) {
response = YES;
} else {
response = [self isAlphaVisibleAtPoint:point forImage:self.buttonBackground];
}
}
self.previousTouchHitTestResponse = response;
return response;
}
另一個測試該點是否在圖層蒙版中的示例代碼,也許您可以更輕松地進行調整:
@implementation MyView
//
// ...
//
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint p = [self convertPoint:point toView:[self superview]];
if(self.layer.mask){
if (CGPathContainsPoint([(CAShapeLayer *)self.layer.mask path], NULL, p, YES) )
return YES;
}else {
if(CGRectContainsPoint(self.layer.frame, p))
return YES;
}
return NO;
}
@end
全文: http : //blog.vikingosegundo.de/2013/10/01/hittesting-done-right/
最后,這就是我所做的:
這種方法似乎比實際繪制數百個UIButton甚至CAShaplayers,甚至在平面圖上具有300多個區域來檢查整個過程是否立即顯示都更為有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.