我有几个UIViews有一些复杂的形状,我通过每个UIView的drawRect:方法绘制。我保存了对路径的引用(通过CGPath属性),我在触摸方法中使用它来检测触摸是否实际在路径或形状内(CGPathContainsPoint)。由于形状的原因,视图的某些区域是透明的(显然,任何不是正方形/矩形的区域都会有透明区域,假设视图的backgroundColor属性设置为clearColor或类似的)。
对于视图最终位于顶部或彼此重叠的情况(经常发生),我正在测试触摸方法(touchesBegan等)以查看触摸是否实际位于CGPath或形状内。如果触摸不在形状内,我将触摸转发到下面的下一个视图,看看它是否通过了该要求。
可悲的是(令我沮丧的是),这与实际绑定到视图的触摸的行为不同。我已经以各种方式解决了这个问题,除了一个特别的问题。每个视图都使用UIRotationGestureRecognizer。但是,如果触摸源自另一个视图的透明区域,并且该视图将该触摸转发到其下方的视图,则永远不会触发UIGestureRecognizer。
我从我知道的每个角度看过这个。我试图想一些实际重新分配或将触摸绑定到适当视图的方法,但我不知道这是否可行。只要视图仅将触摸转发到另一视图,触摸将保持绑定到首先接收触摸的原始视图。
我想知道你是否可以通过子类化UIApplication或UIWindow以及覆盖sendEvent:“方法来做这种方式。我不确定苹果可能会给你什么控制权。我不能做任何可能做的事情正在访问私有API。我真的需要一些方法来重新分配触摸,以便视图认为触摸属于它。
任何想法?'
答案 0 :(得分:2)
你可以通过子类化UIView或子类化UIGestureRecognizer来做到这一点。
通过继承UIView(或其任何子类)并重写
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
您可以决定视图中的哪些点。对于路径之外的点,您只需返回NO
通过继承UIGestureRecognizer(或其任何子类)并覆盖
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
您可以决定手势识别器应该识别的触摸内容。对于路径之外的所有接触,您应该调用(但不是子类)
- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event
自己。
在任何一种情况下,你都需要知道这些点是否在你说你存储的路径中。
如果路径已存储为UIBezierPath
,您只需拨打
- (BOOL)containsPoint:(CGPoint)point
在bezier路径上。可能需要通过调用
将点或触摸转换为与路径相同的视图坐标- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view
或
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view
在你的观点上。
如果路径存储为CGPath,您可以使用
从中创建UIBezierPath[UIBezierPath bezierPathWithCGPath:CGPath];