簡體   English   中英

通過觸摸到 UIWebView 的一部分

[英]Pass through touches to portion of UIWebView

我有一個 UIWebView。使用這樣的東西:

http://blog.evandavey.com/2009/02/how-to-make-uiwebview-transparent.html

.. 我已將 UIWebView 設為透明。 我現在需要能夠將 webview 上的觸摸傳遞到下面的視圖,但只能傳遞到 web 視圖的矩形部分。

所以,假設 webview 是一個正方形,它的中心有一個正方形區域,必須直通觸摸到下面的視圖。

有沒有辦法做到這一點?

這是一種更具體的hitTest操作形式。

首先,創建UIView的子類。 我叫我ViewWithHole

在其 header 中,為UIView定義一個屬性,這將是通過外部視圖的孔。 將其設為IBOutlet

@property (retain) IBOutlet UIView *holeView;

然后覆蓋hitTest 如果該點在孔內返回命中,則返回該點。 否則返回它通常會的。

- (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event;
{
    CGPoint pointInHole = [self convertPoint:point toView:self.holeView];
    UIView *viewInHole = [self.holeView hitTest:pointInHole withEvent:event];

    if (viewInHole)
        return viewInHole;
    else
        return [super hitTest:point withEvent:event];
}

在 Interface Builder 中,或以編程方式放置一個ViewWithHole 按順序在其中放入UIViewUIWebView 使UIView成為holeViewViewWithHole

Interface Builder 配置 ViewWithHole

holeView本身可以是交互式的,或者您可以在其中放置任意數量的交互式視圖。 在這里,我放了一些標准視圖以確保它們有效。 孔內的任何點擊都將發送到它及其子視圖,而不是頂部的UIWebView holeView將像往常一樣接收UIWebView之外的任何點擊。

您可以在洞前顯示任意數量和類型的視圖; 重要的是holeView已正確連接。

我的第一個想法是這樣的:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch * touch = (UITouch *)[touches anyObject];
CGPoint location = [touch locationInView:self];

//min_x,max_x,min_y,max_y are the min and max coord of your rect below

if (CGRectContainsPoint(CGRectMake(min_x,min_y,max_x,max_y),location))
{
     //send the touches to the view below
}

}

如果下面的視圖是靜止的但您沒有提供有關下面視圖的任何信息(如果有按鈕,或者它是否移動......類似的東西),這應該有效......所以......是的......這樣做

您可以創建UIWebView的子類並覆蓋其hitTest:withEvent:pointInside:withEvent:以忽略“漏洞”——但Apple 表示您不應該將 UIWebView 子類化

或者,您可以創建一個 UIView 子類並將 UIWebView 作為子視圖放入其中,然后使其hitTest:withEvent:方法返回 UIWebView 下方的視圖。

這是UIView子類的通用hitTest方法,它優先考慮任何不是 UIWebView 的交互式子視圖,即使它們位於 UIWebView 下面。它沒有任何特定的“漏洞”檢測,但hitTest也是你想那樣做。 在忽略 UIWebView 之前,先算出point是否在洞中。

// - (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event;
// This overrides the usual hitTest method to give priority to objects that are not in a chosen class.
// For this example, that class has been hard-coded to UIWebView.
// This allows the webview to be displayed over other interactive components.
// For the UIWebView case, it would be nice to look at its layout and only return views beneath it in locations where it is transparent, but that information is not obtainable.
- (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event;
{
    UIView *viewFound = nil;
    Class lowPriorityClass = [UIWebView class];
    NSMutableArray *lowPriorityViews = [NSMutableArray array];

    // Search the subviews from front to back.
    NSEnumerator *viewEnumerator = [[self subviews] reverseObjectEnumerator];
    UIView *subview;
    while ((subview = [viewEnumerator nextObject]) && (!viewFound))
    {
        // Save low-priority cases for later.
        if ([subview isKindOfClass:lowPriorityClass])
            [lowPriorityViews addObject:subview];
        else
        {
            CGPoint pointInSubview = [self convertPoint:point toView:subview];
            if ([subview pointInside:pointInSubview withEvent:event])
            {
                // Subviews may themselves have subviews to return.
                viewFound = [subview hitTest:pointInSubview withEvent:event];
                // However, if not, return the subview itself.
                if (!viewFound)
                    viewFound = subview;
            }
        }
    }

    if (!viewFound)
    {
        // At this point, no other interactive views were found, so search the low-priority cases previously stored to see if they apply.
        // Since the lowPriorityViews are already in front to back order, enumerate forward.
        viewEnumerator = [lowPriorityViews objectEnumerator];
        while ((subview = [viewEnumerator nextObject]) && (!viewFound))
        {
            CGPoint pointInSubview = [self convertPoint:point toView:subview];
            if ([subview pointInside:pointInSubview withEvent:event])
            {
                // Subviews may themselves have subviews to return.
                viewFound = [subview hitTest:pointInSubview withEvent:event];
                // However, if not, return the subview itself.
                if (!viewFound)
                    viewFound = subview;
            }
        }
    }

    // All cases dealt with, return whatever was found.  This will be nil if no views were under the point.
    return viewFound;
}

我認為您的問題有一個非常簡單的解決方案......您沒有指定它,但我推斷您不希望用戶與 webview HTML 進行交互。如果是這樣,只需在 webview 上禁用 UserInteractionEnabled接觸會通過。

然后你需要你提到的位於中心的活動視圖。

希望對您有所幫助,如果您需要任何說明,請發表評論。

我有另一個想法:獲得全局點擊。 當有人點擊 iPhone 時,它會向全局sendEvent發送一條消息。 所以你聽它並做你想要的任務。

為此,您需要UIApplication 首先,在 main.c 中使用這個 function

    int retVal = UIApplicationMain(argc, argv, @"myUIApplicationClass" ,nil);

然后執行這個 class:

@implementation BBAplicationDebug

- (void)sendEvent:(UIEvent *)event
{
    [super sendEvent:event];
    NSSet *touches = [event allTouches];
    UITouch *touch = touches.anyObject;
    [[NSNotificationCenter defaultCenter] postNotificationName:@"userClick" object:touch];
}

@end

現在你聽這個 NSNotification 並做所有的檢查:在正確的框架中,有正確的 UIView,等等......

暫無
暫無

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

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