簡體   English   中英

將多個可點擊的形狀添加到UIView

[英]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/

最后,這就是我所做的:

  • 遍歷我需要的所有支架形狀,並創建一個字典,在平面圖圖像上使用其坐標的UIBezierpath和形狀的standNo。
  • 然后,我將這些字典添加到數組中。
  • 輕按屏幕時,我會注意輕按位置的X和Y並遍歷字典數組,並檢查UIBezierpath是否包含由X和Y輕按坐標組成的點。
  • 如果找到一個在其邊界內具有X和Y坐標的形狀,我將使用UIBezierpath並添加fillColor繪制一個CAShapelayer,使其在地圖上顯示。 然后顯示一個alertView,其中顯示有關參展商的更多信息。

這種方法似乎比實際繪制數百個UIButton甚至CAShaplayers,甚至在平面圖上具有300多個區域來檢查整個過程是否立即顯示都更為有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM