1

我有一个 UIWebView。使用这样的东西:

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

.. 我已使 UIWebView 透明。我现在需要能够将 web 视图上的触摸传递到下面的视图,但只能传递到 web 视图的矩形部分。

所以,想象一下 webview 是一个正方形,它的中心有一个正方形区域,必须通过触摸到下面的视图。

有没有办法做到这一点?

4

5 回答 5

3

这是一种更具体的hitTest操纵形式。

首先,创建一个UIView. 我打电话给我ViewWithHole的。

在其标题中,为 a 定义一个属性,该属性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. 按顺序将 aUIView和 a放入UIWebView其中。使. UIView_ holeView_ViewWithHole

Interface Builder 配置 ViewWithHole

holeView本身可以是交互式的,或者您可以在其中放置任意数量的交互式视图。在这里,我放了一些标准视图以确保它们正常工作。孔内的任何点击都将发送到它及其子视图,而不是UIWebView顶部。外面的任何水龙头holeView都将UIWebView照常接收。

您可以在孔前显示任意数量和类型的视图;重要的holeView是正确连接。

于 2012-04-13T22:48:29.230 回答
1

我有另一个想法:获得全局点击。当有人点击 iPhone 时,它​​会向 global 发送一条消息sendEvent。所以你听它并做你想做的任务。

为此,您需要将UIApplication. 首先,在 main.c 中使用这个函数

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

然后实现这个类:

@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 等等……

于 2012-04-13T21:50:50.990 回答
1

我认为您的问题有一个非常简单的解决方案...您没有指定它,但我推断您不希望用户与 webview HTML 交互。如果是这样,只需在 webview 上禁用 UserInteractionEnabled,触摸就会通过。

然后,您需要您提到的位于中心的活动视图。

希望对您有所帮助,如果您需要任何澄清,请发表评论。

于 2012-04-13T18:03:32.833 回答
1

您可以创建一个子类UIWebView并覆盖它hitTest:withEvent:pointInside:withEvent:忽略“洞” - 但Apple说您不应该继承 UIWebView

或者,您可以创建一个 UIView 子类并将 UIWebView 作为子视图放置在其中,然后使其hitTest:withEvent:方法返回 UIWebView 下方的视图。

这是子类的通用hitTest方法UIView,它优先考虑不是 UIWebView 的任何交互式子视图,即使它们位于 UIWebView 下方。它没有任何特定的“洞”检测,但hitTest也是您想要这样做的地方。point在忽略 UIWebView 之前先弄清楚是否在洞中。

// - (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;
}
于 2012-04-08T23:24:02.950 回答
1

我的第一个想法是这样的:

- (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
}

}

如果下面的视图是静止的,但您没有提供有关下面视图的任何信息(如果有按钮,或者它是否移动......类似的东西),这应该可以工作,所以......是的......这样做

于 2012-04-07T19:08:53.653 回答