繁体   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