2011-06-30 30 views
4

我在UIView上繪製了一個圖,該圖由UIScrollView包含,因此用戶可以水平滾動查看整個圖形。iOS:我可以重寫UIScrollView的捏入/拖出行爲嗎?

現在我想在用戶用兩個手指捏合時縮放圖形,而不是在X和Y方向上以相同速率放大視圖,而只想通過更改X來縮放X方向規模,而不改變Y的規模。

我想我必須抓住捏入/拖出手勢並重繪圖形,覆蓋默認的縮放行爲。

但是有沒有辦法做到這一點?

我一直在UIScrollView上遇到捏手勢非常困難,因爲它開始滾動時取消觸摸。即使在UIScrollView取消觸摸之後,我也希望縮放工作。 :(

感謝, 庫拉

回答

11

儘管無法刪除現有的捏手勢識別器,但可以禁用它,然後添加自己的:

// Disable existing recognizer 
for (UIGestureRecognizer* recognizer in [_scrollView gestureRecognizers]) { 
    if ([recognizer isKindOfClass:[UIPinchGestureRecognizer class]]) { 
     [recognizer setEnabled:NO]; 
    } 
} 

// Add our own 
UIPinchGestureRecognizer* pinchRecognizer = 
    [[UIPinchGestureRecognizer alloc] initWithTarget:self 
              action:@selector(pinch:)]; 
[_scrollView addGestureRecognizer:pinchRecognizer]; 
[pinchRecognizer release]; 

然後在

- (void) pinch:(UIPinchGestureRecognizer*)recognizer { .. } 

使用

[recognizer locationOfTouch:0 inView:..] 
[recognizer locationOfTouch:1 inView:..] 

找出如果用戶被水平或垂直地夾持。

+0

這是一個簡單的解決方案。 :)謝謝edsko! – Taka

+0

即使不禁用退出手勢,您也可以添加新手勢。 –

+1

來自遙遠未來的快速評論:在撰寫答案後三個月出現的iOS 5添加了「 - [UIScrollView pinchGestureRecognizer]」,因此您不必進行線性搜索,並希望Apple沒有做任何事情太不正統。 – Tommy

1

你應該能夠繼承的UIScrollView並重寫的touchesBegan:方法不要調用[超級的touchesBegan:]而是調節變焦,只要你喜歡:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    //Anything you want. Probably you would want to store all the touches 
    //or their values, so that you can compare them to the touches 
    //in the touchesEnded: method, 
    //thus letting you know what the pinch amount was 
} 

如果你願意,你就可以判斷它是否是一個捏或沒有,如果它不是,調用超級方法,只有自己處理定製捏。

+0

因爲'UIScrollView'現在使用多個手勢識別器,並且在這些方法和'touch'方法之間的交互作用中,這些方法通常會在嘗試實現「拖拽」時失敗 - 滾動視圖中我不得不用手勢識別器來做 – bshirley

+0

這很有道理,我猜。雖然如果你仍然想這樣做,你應該能夠代替UIView的子類並獲得它的觸摸事件,然後使用它們來操縱UIScrollView放置在UIView之上? –

+0

馬特,thans爲您的答覆。我試過了,但一旦滾動開始,觸摸就會被UIScrollView取消,之後就不能再處理它們了。如果我繼承UIScrollView或UIView的子類並將其放在UIScrollView上,這也是一樣的。 – Taka

5

而應該訪問gestureRecognizers(定義的UIView ),有幾個人正在使用的滾動視圖,

弄清楚哪一個是掐識別和呼叫removeGestureRecognizer:上滾動視圖,然後創建你自己的,並把它做的工作,與addGestureRecognizer:添加回去。

這些都是公開的API, 識別器和什麼樣的順序,他們是不是(目前), 所以訪問他們時,程序的防守

(這是操作的UIKit意見完全有效的方式,和蘋果將不會/不應該有問題 - 雖然他們不能保證它可以在任何未來的版本中發揮作用)

+0

+1我正在使用代碼示例對此進行解答,但這是需要做的,手勢識別器在觸摸事件之前觸發,通常不會發送touchesBegan和類似事件。循環通過gestureRecognizers並查找任何是KindOfClass:[UIPinchGestureRecognizer類] – Joe

+0

bshirley&Joe,感謝您的回覆。我可以在UIScrollView實例上找到3個gestureRecognizers,其中一個是UIScrollViewPinchGestureRecognizer。我試圖刪除它,並添加了我的自定義手勢識別器,但它崩潰,因爲UIScrollView總是嘗試將消息專門發送到已被刪除和釋放的UIScrollViewPinchGestureRecognizer對象。我想到了一個想法來調用[UIGestureRecognizer removeTarget:action:]來刪除默認的夾點動作並添加一個新動作,但該動作似乎是[UIScrollView handleGesture:],這是沒有記錄。 :( – Taka

+0

添加您的識別器,獲取該識別器的暫掛,然後告訴識別器,它需要您的失敗才能成功 – bshirley

0

Edsko & bshirley的答案很好,但他們不知道在哪裏放置代碼。

首先,我將它放在viewDidLoad方法中,但在scrollview中找不到捏手勢識別器(可能因爲我的scrollview是IBOutlet)。

然後我試着在viewWillAppearviewDidAppearUIPinchGestureRecognizer在這裏。

+0

插座尚未設置在viewDidLoad ... – mramosch

+0

是的。你是對的。還有'viewDidLayoutSubviews' – Martin

相關問題