のサブクラスを作成して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;
}