1

UIWebViewがあります。このようなものを使用する:

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

..UIWebViewを透過的にしました。Webビューのタッチを下のビューに渡すことができる必要がありますが、Webビューの長方形の部分のみです。

したがって、Webビューが正方形であり、中央に正方形の領域があり、下のビューにパススルータッチする必要があると想像してください。

これを行う方法はありますか?

4

5 に答える 5

3

これは、より具体的なhitTest操作形式です。

まず、のサブクラスを作成しますUIView。私は私のと呼んだViewWithHole

UIViewそのヘッダーで、外部ビューを通る穴となるaのプロパティを定義します。これを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とaUIWebViewをこの順序で入れます。UIViewのを作成holeViewViewWithHoleます。

ViewWithHoleを設定するInterfaceBuilder

holeViewそれ自体がインタラクティブにすることも、その中に任意の数のインタラクティブビューを配置することもできます。ここでは、それらが機能することを確認するために、いくつかの標準ビューをそこに配置します。穴内のタップは、上部ではなく、穴とそのサブビューに送信されUIWebViewます。の外側のタップは通常どおりholeViewに受信されます。UIWebView

穴の前に任意の数とタイプのビューを表示できます。重要なのは、holeViewが正しく接続されていることです。

于 2012-04-13T22:48:29.230 に答える
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 に答える
1

のサブクラスを作成してUIWebViewオーバーライドしhitTest:withEvent:pointInside:withEvent:「穴」を無視することもできますが、AppleはUIWebViewをサブクラス化すべきではないと言っています

または、UIViewサブクラスを作成し、その中にUIWebViewをサブビューとして配置してから、そのhitTest:withEvent:メソッドがUIWebViewの下にビューを返すようにすることもできます。

これはサブクラスの一般的なhitTestメソッドでありUIView、UIWebViewの下にある場合でも、UIWebViewではないインタラクティブなサブビューを優先します。特定の「穴」検出はありませんが、それhitTestを実行したい場所でもあります。pointUIWebViewを無視する前に、が穴にあるかどうかを確認してください。

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

あなたの問題には非常に簡単な解決策があると思います...あなたはそれを指定しませんが、ユーザーにWebviewHTMLを操作させたくないと思います。その場合は、WebビューでUserInteractionEnabledを無効にするだけで、タッチが通過します。

次に、あなたが述べたように、中央にアクティブなビューを配置する必要があります。

何か説明が必要な場合は、コメントしてください。

于 2012-04-13T18:03:32.833 に答える
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があるかなど...

于 2012-04-13T21:50:50.990 に答える