简体   繁体   English

通过触摸到 UIWebView 的一部分

[英]Pass through touches to portion of UIWebView

I have a UIWebView. Using something like this:我有一个 UIWebView。使用这样的东西:

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

.. I have made the UIWebView transparent. .. 我已将 UIWebView 设为透明。 I now need to be able to pass though touches on the webview to the view below, but only on a rectangular portion of the web view.我现在需要能够将 webview 上的触摸传递到下面的视图,但只能传递到 web 视图的矩形部分。

So, imagine the webview is a square, and it has a square area in the centre which must pass-thru touches to the view below.所以,假设 webview 是一个正方形,它的中心有一个正方形区域,必须直通触摸到下面的视图。

Is there a way to do this?有没有办法做到这一点?

This is a more specific form of hitTest manipulation.这是一种更具体的hitTest操作形式。

First, create a subclass of UIView .首先,创建UIView的子类。 I called mine ViewWithHole .我叫我ViewWithHole

In its header, define a property for a UIView that will be the hole through the outer view.在其 header 中,为UIView定义一个属性,这将是通过外部视图的孔。 Make this an IBOutlet .将其设为IBOutlet

@property (retain) IBOutlet UIView *holeView;

Then override hitTest .然后覆盖hitTest If the point is returns a hit within the hole, return that.如果该点在孔内返回命中,则返回该点。 Otherwise return what it usually would.否则返回它通常会的。

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

In Interface Builder, or programmatically, place a ViewWithHole .在 Interface Builder 中,或以编程方式放置一个ViewWithHole Put a UIView and a UIWebView within it, in that order.按顺序在其中放入UIViewUIWebView Make the UIView the holeView of the ViewWithHole .使UIView成为holeViewViewWithHole

Interface Builder 配置 ViewWithHole

The holeView can itself be interactive, or you can put any number of interactive views within it. holeView本身可以是交互式的,或者您可以在其中放置任意数量的交互式视图。 Here, I put a few standard views in there to make sure they work.在这里,我放了一些标准视图以确保它们有效。 Any taps on within the hole will be sent to it and its subviews, not the UIWebView on top.孔内的任何点击都将发送到它及其子视图,而不是顶部的UIWebView Any taps outside the holeView will be received by the UIWebView as usual. holeView将像往常一样接收UIWebView之外的任何点击。

You can have any number and type of views displayed in front of the hole;您可以在洞前显示任意数量和类型的视图; all that matters is that the holeView is properly connected.重要的是holeView已正确连接。

my firsth idea is something like this:我的第一个想法是这样的:

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

}

this should work if the view below is stationary but you haven't given any information about the view below (if there's buttons, or if it moves..stuff like that) so...yea..do that如果下面的视图是静止的但您没有提供有关下面视图的任何信息(如果有按钮,或者它是否移动......类似的东西),这应该有效......所以......是的......这样做

You could create a subclass of UIWebView and override its hitTest:withEvent: and pointInside:withEvent: to disregard the 'hole' - but Apple say you shouldn't subclass UIWebView .您可以创建UIWebView的子类并覆盖其hitTest:withEvent:pointInside:withEvent:以忽略“漏洞”——但Apple 表示您不应该将 UIWebView 子类化

Or, you could create a UIView subclass and place the UIWebView within it as a subview, then make its hitTest:withEvent: method return views beneath the UIWebView.或者,您可以创建一个 UIView 子类并将 UIWebView 作为子视图放入其中,然后使其hitTest:withEvent:方法返回 UIWebView 下方的视图。

Here is a generic hitTest method for a UIView subclass, that gives priority to any interactive subviews that aren't UIWebView, even if they're underneath the UIWebView. It doesn't have any specific 'hole' detection, but hitTest is also where you want to do that.这是UIView子类的通用hitTest方法,它优先考虑任何不是 UIWebView 的交互式子视图,即使它们位于 UIWebView 下面。它没有任何特定的“漏洞”检测,但hitTest也是你想那样做。 Just work out if the point is in the hole before disregarding the UIWebView.在忽略 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;
}

I think that there is a very easy solution to your problem... You do not specify it, but I deduce that you don't want the user to interact with the webview HTML. If that is so, just disable UserInteractionEnabled on the webview and the touches will pass trough.我认为您的问题有一个非常简单的解决方案......您没有指定它,但我推断您不希望用户与 webview HTML 进行交互。如果是这样,只需在 webview 上禁用 UserInteractionEnabled接触会通过。

Then you need your active view located in the center as you mentioned.然后你需要你提到的位于中心的活动视图。

I hope it helps, if you need any clarification just comment it.希望对您有所帮助,如果您需要任何说明,请发表评论。

I have another idea: get the global click.我有另一个想法:获得全局点击。 When someone click in iPhone, it send a message to global sendEvent .当有人点击 iPhone 时,它会向全局sendEvent发送一条消息。 So you listen to it and do the task you want.所以你听它并做你想要的任务。

To do this, you need to subclass the UIApplication .为此,您需要UIApplication First, in main.c use this function首先,在 main.c 中使用这个 function

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

then implement this class:然后执行这个 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

Now you listen this NSNotification and do all the checks: Is in the correct frame, has the correct UIView, etc, etc...现在你听这个 NSNotification 并做所有的检查:在正确的框架中,有正确的 UIView,等等......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM