2012-04-05 27 views
1

我有一個UIWebView。使用這樣的事情:將觸摸傳遞給UIWebView的一部分

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

..我已經做了一個UIWebView透明。我現在需要能夠通過webview訪問下面的視圖,但只能在Web視圖的矩形部分。

所以,想象一下webview是一個正方形,它的中心有一個方形區域,它必須通過下面的視圖。

有沒有辦法做到這一點?

+0

你能提供你想要做的事情嗎?特別是UIWebView中的'hole'是固定在視圖後面還是需要滾動HTML內容? – Dondragmer 2012-04-11 04:56:59

+0

html不滾動,頁面不夠深。所以我設置了webView.scrollView.scrollEnabled = NO – cannyboy 2012-04-13 15:14:44

回答

3

這是一個更具體的形式hitTest操縱。

首先,創建一個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。按照該順序將UIViewUIWebView置於其中。製作ViewWithHoleUIViewholeView

Interface Builder configuring ViewWithHole

holeView本身可以互動,或者你可以把其中的任何數量的交互視圖。在這裏,我提出了一些標準的意見,以確保它們的工作。洞內的任何水龍頭將發送給它和它的子視圖,而不是頂部的UIWebView。像往常一樣,UIWebView將收到holeView以外的任何水龍頭。

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

1

我firsth的想法是這樣的:

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

} 

這應該工作,如果下面的觀點是靜止的,但是你沒有給下面關於視圖的任何信息(如果有按鈕,或者如果它的動作。 .stuff這樣的),所以...... yea..do是

1

您可以創建的UIWebView一個子類,並覆蓋其hitTest:withEvent:pointInside:withEvent:無視「洞」 - 但Apple say you shouldn't subclass 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; 
} 
1

我認爲有一個很容易解決您的問題...你不指定,但我推斷你不希望用戶與web視圖HTML互動。如果是這樣,只需在Web視圖上禁用UserInteractionEnabled,觸摸將通過槽。

然後,您需要您提到的位於中心的活動視圖。

我希望它有幫助,如果您需要任何澄清只是評論它。

1

我有另一個想法:獲得全局點擊。當有人點擊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,等等...