我相信如果没有子类化这是不可能的。如果有人能证明我错了,我很乐意看到他们的解决方案。无论如何,这就是我解决它的方法:
首先,我子类视图A
,我调用子类ParentView
。ParentView 需要指向B1
和的指针B2
。我还添加了一个额外的指针,稍后用于存储当前选定的视图。然后,我覆盖hitTest
:
@interface ParentView : UIView
@property (nonatomic, strong) UIView* viewB1;
@property (nonatomic, strong) UIView* viewB2;
@property (nonatomic, strong) UIView* currentlyTouchedView;
@end
@implementation ParentView
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (self.currentlyTouchedView == nil) {
if (CGRectContainsPoint(self.viewB1.frame, point)) {
self.currentlyTouchedView = viewB1;
}else if(CGRectContainsPoint(self.viewB2.frame, point)) {
self.currentlyTouchedView = viewB2;
}
}else {
if (!CGRectContainsPoint(self.currentlyTouchedView.frame, point)) {
return nil;
}
}
return [super hitTest:point withEvent:event];
}
@end
所以,这段代码所做的是,它存储了第一次触摸的视图。如果已经存储了一个,它会返回 nil on hitTest
,这会消耗掉任何额外的触摸事件。
现在,在哪里currentlyTouchedView
设置回零?为此,我继承UIWindow
并覆盖sendEvent
以检查所有触摸是否已结束:
@implementation EventOverrideWindow
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
BOOL allTouchesEnded = YES;
for (UITouch* touch in event.allTouches) {
if (touch.phase != UITouchPhaseCancelled && touch.phase != UITouchPhaseEnded) {
allTouchesEnded = NO;
break;
}
}
if (allTouchesEnded) {
ParentView* parentView = ((AppDelegate*)[UIApplication sharedApplication].delegate).parentView;
parentView.currentlyTouchedView = nil;
}
}
@end
我知道这不是一个非常优雅的解决方案,如果有人有更好的主意,我将不胜感激。