2012-05-11 41 views
0

我有幾個UIViews有一些複雜的形狀,我通過每個UIView的drawRect:方法繪製。我保存了對路徑的引用(通過CGPath屬性),並在觸摸方法中使用它來檢測觸摸是否實際位於路徑或形狀內(CGPathContainsPoint)。由於形狀的原因,視圖中有些區域是透明的(顯然,任何非正方形/矩形的區域都會有透明區域,假設視圖的backgroundColor屬性設置爲clearColor或其他類型)。是否可以決定UITouch綁定到哪個視圖?

對於視圖最終位於頂部或彼此重疊的情況(經常發生),我正在測試觸摸方法(touchesBegan等)以查看觸摸是否實際位於CGPath或形狀內。如果觸摸不在形狀內,我會將觸摸轉發到下面的下一個視圖,以查看它是否依次通過了該要求。

不幸的是(儘管我非常沮喪),但這並不像觸摸實際上綁定到視圖一樣。除了特別之外,我已經以各種方式解決了這個問題。每個視圖都使用UIRotationGestureRecognizer。但是,如果觸摸起源於另一個視圖的透明區域,並且該視圖將該觸摸轉發到其下的視圖,那麼UIGestureRecognizer將不會被觸發。

我已經從我知道如何的每個角度看過這個。我試圖想出一些方法來實際重新分配或將觸摸綁定到適當的視圖,但我不知道這是否可能。只要視圖只是將觸摸轉發到另一個視圖,觸摸將保持綁定到先接觸觸摸的原始視圖。我不知道你是否可以這樣做,通過繼承UIApplication或UIWindow並覆蓋sendEvent:「方法。我不確定蘋果公司可能會給你什麼樣的控制權,我不能做任何事情。可能是訪問私有API的,我真的只需要一些方法來重新分配觸摸,以便視圖認爲觸摸屬於它

任何想法?

回答

2

您既可以由子類的UIView或子類UIGestureRecognizer做到這一點。

子類的UIView

通過子類的UIView(或它的子類)和壓倒一切的

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 

你可以決定什麼點被認爲是在您的視野內,對於路徑外的點,您只需返回NO

子類UIGestureRecognizer

通過繼承UIGestureRecognizer(或任何其子類)和壓倒一切的

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 

你可以決定什麼接觸手勢識別應該承認。對於您應該致電的路徑外的所有觸及(但不是子類)

- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event 

對自己。


點在路徑內嗎?

無論哪種情況,您都需要知道這些點是否在您所存儲的路徑的內部。

如果路徑已經被存儲爲UIBezierPath是你可以簡單地調用

- (BOOL)containsPoint:(CGPoint)point 

在貝塞爾路徑。該點或觸摸可能需要通過調用

- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view 

- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view 

在您的視圖轉換爲相同的觀點座標的路徑。

如果路徑存儲爲CGPath你可以使用

[UIBezierPath bezierPathWithCGPath:CGPath]; 
+0

創建它UIBezierPath雖然這並不能完全回答這個問題,它讓我在正確的軌道上。在進一步研究之後,我發現這篇博文完全回答了這個問題:http://bynomial.com/blog/?p=74我接受了答案,因爲這是一個很好的努力,並幫助我弄清楚了什麼需要知道。 – daveMac

+0

有什麼我可以澄清的? –

+0

由於每個視圖都是通過覆蓋觸摸方法(touchesBegan,moving等)來「攔截」觸摸, - (BOOL)pointInside:(CGPoint)指向withEvent:(UIEvent *)事件永遠不會被調用,除非我觸及視圖。但通過遵循上面提供的鏈接,我可以覆蓋基礎子視圖的hitTest:方法,然後使用pointInside:來確定它是否是有效的觸摸。另外,雖然我確定你的意思是「路徑內的點?」部分,這是無關緊要的,因爲我說我已經這樣做了。不過謝謝 – daveMac

相關問題