2011-11-06 50 views
5

測試用例是很容易複製:下載蘋果的PhotoScroller示例應用程序,並嘗試去適應它,這樣平移(包括周圍縮放圖像,以及之間的每個圖像)只能用兩個手指。分頁的UIScrollView用兩個手指平移和縮放

設置panGestureRecognizer同時爲pagingScrollViewimageScrollView只接受一個最小&最大的2個觸摸似乎是一個良好的開端,但它不工作。它可以讓你用兩根手指在圖像上滾動*,但是分頁不起作用。

我已經嘗試了很多設置和自定義手勢識別器的組合,而且我有點難住。是一個自定義的滾動視圖子類將有任何用處,或者我可以以某種方式操縱滾動視圖委託方法,使其工作?

* 編輯:其實,它在這種情況下不會正常滾動。視圖不再像單觸一樣順暢地滑動...

更新:我仍然在爲這一個而努力。我希望從誰已與UIGestureRecognizer S和UIScrollView在扮演各地的人一些輸入。

編輯

設置ImageScrollView類只接受兩個亮點:

- (id)initWithFrame:(CGRect)frame 
{ 
    // ... 
    // Template code 
    // ... 

    [self.panGestureRecognizer setMinimumNumberOfTouches:2]; 
    [self.panGestureRecognizer setMaximumNumberOfTouches:2]; 
} 

設置PhotoViewControllerpagingScrollView只接受兩個亮點:

- (void)loadView 
{ 
    // ... 
    // Template code 
    // ... 

    [pagingScrollView.panGestureRecognizer setMinimumNumberOfTouches:2]; 
    [pagingScrollView.panGestureRecognizer setMaximumNumberOfTouches:2]; 
} 

這些修改是直接在PhotoS上面製作的croller示例應用程序。我希望這些簡單的改變爲兩個手指交互工作,但是副作用都是奇數(如上所述)。

+0

正在下載。 108mb o_O – 0xSina

+0

@PragmaOnce:是的,很抱歉鏈接這麼大的樣本。它包含分頁滾動視圖的所有全尺寸和平鋪圖像。漂亮的圖片沒有必要證明我的觀點,但嘿...! – Stuart

+1

UIScrollView有它自己的私人手勢識別器。即使是暴露的panGestureRecognizer是一個私人類。 'NSLog(@「%@」,[pagingScrollView valueForKeyPath:@「gestureRecognizers.class」]);' - >'(UIScrollViewDelayedTouchesBeganGestureRecognizer,UIScrollViewPanGestureRecognizer,UIScrollViewPagingSwipeGestureRecognizer)''。我認爲你需要選擇一個不同的用戶界面。 –

回答

0

這樣看來,這是根本無法支持,或非常非常困難的(即滾動從頭開始自己的滾動視圖)。我使用了Apple技術支持事件,他們無法提供幫助。如果解決方案變得可用,我會很高興地將其標記爲接受的答案!

+0

完全不可能 - 易於修復... - ;-)查看我的詳細解答... – mramosch

0

子類似乎是去與此

的文檔指出,你可以操縱的手勢如何滾動通過子類化處理方式。

UIScrollView Class Reference

具體地說

子類可以覆蓋所述 touchesShouldBegin:withEvent:方法inContentView :, pagingEnabled,和 touchesShouldCancelInContentView:方法(其由 滾動視圖調用)來影響如何滾動視圖處理滾動手勢。

你也應該看看這個帖子SO,Scrolling with two fingers with a UIScrollView

+0

感謝您的回覆,我很感激。然而 - 暫時關鍵 - 這是一個更具體問題的非常通用的答案。 'ImageScrollView'已經被子類化了,我也嘗試過使用分頁滾動視圖的子類化,但是沒有用。我之前看到過鏈接的SO帖子,儘管過去它對我有用,但答案實際上都是過時的(即使是通過滾動視圖的手勢識別器迭代的答案 - 在iOS 5中也可以更容易地實現使用我的問題中的代碼)。 – Stuart

+0

我希望你能明白我想給出一個答案,提供更詳細的洞察,以瞭解如何定製一個子類以實現所需的行爲。例如,因爲'touchesShouldBegin ...'&'touchesShouldCancel ...'只在每個觸摸序列開始時被調用一次,所以如何處理'ImageScrollView'應該平移(放大時)的情況,然後當滾動到達圖像的邊緣時,分頁滾動視圖應該接管? – Stuart

+0

我可以充分意識到,我希望你能得到更有幫助的答案。我會看看我是否可以研究一些。我已經使用scrollviews手勢識別器,但不是這種情況。 –

0

問題

UIPanGestureRecognizer被下方的UIScrollView(其遺憾的是也影響UIPageViewController)的maximumNumberOfTouches不表現爲預期 - 的minimumNumberOfTouches然而,總是有限的它的下端正確。

當監測這些參數時,他們似乎完成了他們的工作 - 只是UIScrollView不尊重他們而忽略他們的價值!


補救措施

你可以在我的答案的解決方案:

UIScrollView scrolling only with one finger


BTW:

one手指和two指平移體驗之間的差異是因爲用一個手指,你正在使用的panGestureRecognizer。用兩個手指 pinchGestureRecognizer(它也可以同時平移)開始,並且你沒有減速階段,並且在釋放你的手指後視圖立即停止平移和縮放。停用pinchGestureRecognizer,你會看到panGestureRecognizer接管 - 即使兩個手指 - 和平移光滑再次... ;-)


方法同步 - 瞧等...

一個完美的同時手指2和 scrolling行爲 zooming代表

回調:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
    self.pinchGestureRecognizer.enabled = NO; 
} 

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { 
    self.pinchGestureRecognizer.enabled = NO; 
} 

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 
    self.pinchGestureRecognizer.enabled = YES; 
} 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    self.pinchGestureRecognizer.enabled = YES; 
} 

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {  
    self.panGestureRecognizer.enabled = NO; 
} 

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {  
    self.panGestureRecognizer.enabled = YES; 
} 

Fast pinch開始縮放!
Fast pan開始平移!

用兩個新手指在屏幕上向下停止減速平移並再次開始拖動不會讓笨拙的pinchGestureRecognizer接管(默認),而是順利地進入下一個平移/減速階段 - 就像用一根手指一樣!


對於完美:

放2根手指在屏幕上 - 都不動,現在 - 如果不啓動前0.5秒內捏zooming被鎖定,只有panning可用:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { 

    if ([gestureRecognizer.view isMemberOfClass:[MY_CustomScrollView class]]) { 

     NSLog(@"IN SCROLL-VIEW..."); 
     if (gestureRecognizer == self.pinchGestureRecognizer) { 
      if (_pinchGestureLocked) { 
       NSLog(@"...but TOO late for zooming..."); 
       return NO; 
      } else { 
       NSLog(@"...ZOOMING + PANNING..."); 
       return YES; 
      } 
     } else if (gestureRecognizer == self.panGestureRecognizer){ 
      if (gestureRecognizer.numberOfTouches > 2) { 
       NSLog(@"...but TOO many touches for PANNING ONLY..."); 
       return NO; 
      } else { 
       NSLog(@"...PANNING..."); 
       return YES; 
      } 
     } else { 

      NSLog(@"...NO PAN or PINCH..."); 
      return YES; 
     } 

    } else { 
     NSLog(@"NOT IN SCROLL-VIEW..."); 
    } 

    return YES; 

} 

BOOL _pinchGestureLocked = NO; 

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    [super touchesBegan:touches withEvent:event]; 
    _pinchGestureLocked = YES; 
} 

- (void) touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    [super touchesCancelled:touches withEvent:event]; 
    _pinchGestureLocked = NO; 
} 

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    [super touchesEnded:touches withEvent:event]; 
    _pinchGestureLocked = NO; 
} 

快樂手勢識別!