通过触摸到UIWebView的一部分

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

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

..我已经使UIWebView透明。 我现在需要能够通过webview浏览到下面的视图,但只能在web视图的矩形部分。

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

有没有办法做到这一点?

这是一个更具体的hitTest操作forms。

首先,创build一个UIView的子类。 我叫我的ViewWithHole

在它的头文件中,为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]; } 

在界面生成器,或编程方式,放置一个ViewWithHole 。 把一个UIView和一个UIWebView ,按顺序。 让UIView成为holeViewViewWithHole

Interface Builder配置ViewWithHole

holeView本身可以是交互式的,也可以在其中放置任意数量的交互式视图。 在这里,我把一些标准的意见,以确保他们的工作。 在洞内的任何水龙头将被发送到它和它的子视图,而不是顶部的UIWebView 。 任何在holeView之外的holeView将像往常一样被UIWebView接收。

您可以在孔的前面显示任意数量和types的视图; 所有重要的是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 } } 

这应该工作,如果下面的视图是固定的,但你没有给出任何关于下面的观点(如果有button,或者如果移动..stuff那样)的信息,所以… yea..do

你可以创build一个UIWebView的子类,并重写它的hitTest:withEvent:pointInside:withEvent:忽略这个“洞” – 但是苹果说你不应该子类化UIWebView 。

或者,您可以创build一个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; } 

我认为有一个非常简单的解决scheme,您的问题…你没有指定它,但我推断,你不希望用户与Web视图的HTML交互。 如果是这样的话,只需在Web视图上禁用UserInteractionEnabled,触摸将通过槽。

那么你需要你提到的位于中心的主动视图。

我希望它有帮助,如果你需要任何澄清只是评论它。

我有另一个想法:获得全局点击。 当有人点击iPhone时,它会向全球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等,等等…