2012-10-12 96 views
4

我正在構建一個iPad應用程序,我需要使用兩個視圖之間提供的分隔視圖來調整視圖的功能。分隔視圖只是兩個半屏內容視圖之間的20px高度視圖 - 請參閱附加圖像。iOS:用於平滑滾動和輕彈視圖的手勢識別器

當用戶向上或向下滾動此分隔視圖時,兩個內容視圖都會相應地更改其大小。我已經擴展了UIView,並使用touchMoved代表實現了此代理,代碼如下代碼touchesMoved中給出的代碼。它工作正常。 TouchMoved缺少的唯一東西是你無法直接將分隔視圖輕彈到頂部或底部。你必須一直拖到頂部或底部!

爲了支持彈出視圖,我嘗試了UIPanGestureRecognizer,但我沒有看到順利的拖動。設置父級的分割位置將調整兩個內容視圖,如代碼中所示。當我在UIGestureRecognizerStateChanged狀態下處理分割位置更改時,只需觸摸分隔視圖就可以將其滑動到頂部或底部。在UIGestureRecognizerStateEnded中處理分割位置變化的方法相同,但我沒有看到使用dividerview滾動調整大小的內容視圖!

有人可以告訴我如何實現平滑滾動的分隔視圖與調整內容視圖(如touchMoved)和輕彈視圖?任何替代方法也可以。謝謝。

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    if (touch) { 
     CGPoint lastPt = [touch previousLocationInView:self]; 
     CGPoint pt = [touch locationInView:self]; 
     float offset = pt.y - lastPt.y; 
     self.parentViewController.splitPosition = self.parentViewController.splitPosition + offset; 
    } 
} 

- (void)handlePan:(UIPanGestureRecognizer*)recognizer { 

    CGPoint translation = [recognizer translationInView:recognizer.view]; 
    CGPoint velocity = [recognizer velocityInView:recognizer.view]; 

    if (recognizer.state == UIGestureRecognizerStateBegan) { 
    } else if (recognizer.state == UIGestureRecognizerStateChanged) { 
     // If I change split position here, I don't see smooth scrolling dividerview...it directly jumps to the top or bottom! 
     self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y; 
    } else if (recognizer.state == UIGestureRecognizerStateEnded) { 
     // If I change split position here, the same thing happens at end and I don't see my divider view moving with my scrolling and resizing my views. 
     self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y; 
    } 
} 

初始屏幕

Initial screen

通過滾動朝底部分隔視圖增加頂視圖大小。

Increased top view size by scrolling divider view

頂視圖完全隱藏在這裏,但我必須滾動分頻器檢視所有 頂部的方式。我想拂去分頻器視圖,以便它直接 從任何位置進入到頂部

Top view is totally hidden here but I have to scroll divider view all the way to top. I want to flick the divider view so that it directly goes from any position to top.

回答

7

如果我理解正確的話,你這裏有兩個獨立的問題。

1st:使用GestureRecognizer時出現'不平滑'拖動。代碼中的問題是,每次GR調用它的處理方法時,都會添加翻譯。由於翻譯是連續測量的,因此每次調用時都會添加一個更高的值(即第一個調用將在分割位置添加10,第二個20,第三個30等等)。

爲了解決這個問題,你應該翻譯設置爲零您已經更新了分割位置後:

- (void)handlePan:(UIPanGestureRecognizer*)recognizer { 

    CGPoint translation = [recognizer translationInView:recognizer.view]; 

    if (recognizer.state == UIGestureRecognizerStateChanged) { 
     self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y; 
    } 
    [recognizer setTranslation:CGPointZero inView:recognizer.view]; 
} 

第二:爲了讓用戶輕彈分割位置更靠近頂部或底部,你可以檢查UIGestureRecognizerStateEnded中的速度,並且如果它立即將分割位置設置爲頂部或底部,則會立即執行某個值。

但使用UISwipeGestureRecognizer可能會更方便。

- (void)handleSwipe:(UISwipeGestureRecognizer *)gr 
{ 
    if (gr.direction == UISwipeGestureRecognizerDirectionUp){ 
     [self.parentViewController moveSplitViewToTop]; 
    } 
    else if (gr.direction == UISwipeGestureRecognizerDirectionDown){ 
     [self.parentViewController moveSplitViewToBottom]; 
    } 
} 

在這種情況下,可能有必要(不知道,也許它不是)要求SwipeGR通過設置失敗的PanGR觸發前:

[panGestureRecognizer requireGestureRecognizerToFail:swipeGestureRecognizer]; 

希望這有助於。

編輯: 關於你的評論,我假設頻率你的意思是速度。如果你只使用PanGR,你可以修改上面的代碼。像這樣:

- (void)handlePan:(UIPanGestureRecognizer*)recognizer { 

    CGPoint translation = [recognizer translationInView:recognizer.view]; 
    CGPoint velocity = [recognizer velocityInView:recognizer.view]; 

    if (recognizer.state == UIGestureRecognizerStateChanged) { 
     self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y; 
    } 
    else if (recognizer.state == UIGestureRecognizerStateEnded){ 
     if (velocity.y > someValue){ 
      [self.parentViewController moveSplitViewToBottom]; 
     } 
     else if (velocity.y < someValue){ 
      [self.parentViewController moveSplitViewToTop]; 
     } 
    } 
    [recognizer setTranslation:CGPointZero inView:recognizer.view]; 
} 

我不確定速度是否已簽名,如果沒有,您必須再次檢查if-block中的翻譯。

+0

我試過滑動手勢,但由於10px高度視圖,該事件沒有發生!儘管你的Pan手勢識別器解決方案看起來很有趣我不知道翻譯概念。關於頻率,我試過這樣做,但頻率是以座標的形式出現的,所以我不確定我怎麼測量頻率?請你爲此添加一些示例代碼。謝謝。 – applefreak

+0

我編輯了我的答案,請檢查是否有幫助。 – Tobi

+0

完美。這就像一個魅力。非常感謝你。設置翻譯爲CGPointZero是關鍵! :)我已經完全刪除了touchMoved,它的工作非常好,只是與潘! – applefreak