2014-01-06 23 views
10

是否可以在UITableView或UIScrollView中添加管理單元位置?我的意思是,如果我按下按鈕或調用某種方法來自動滾動到某個位置,我的意思是如果我滾動我的滾動視圖或表格視圖圍繞特定點(例如0, 30),它會自動捕捉到它並留在這?因此,如果我的滾動視圖或表格視圖滾動,然後用戶放開中間0, 250, 35,它會自動「捕捉」並滾動?我可以想象,可能會在if語句中測試該位置是否落在UIScrollView的scrollViewDidEndDragging:WillDecelerate:scrollViewWillBeginDecelerating:方法的該區域中,但我不確定如何在UITableView的情況下實現此方法。任何指導將不勝感激。在UITableView或UIScrollView中添加管理單元位置

+0

你實際上是在正確的路線上。你能否粘貼你試過的一些代碼? – Pavan

+0

@Pavan請看我的答案。 – Milo

+0

我已經發布了你的帖子Milo,並且我也回覆了你的帖子。如果我爲您發佈了一個xcode項目,以瞭解如何正確執行該操作,這樣您就可以擁有一個動態滾動視圖,您不需要不斷地對scrollview委託方法進行更改?這將是一個更清潔的解決方案好友:)讓我知道 – Pavan

回答

22

像帕文指出,scrollViewWillEndDragging:withVelocity:targetContentOffset:是你應該使用的方法。它適用於表格視圖和滾動視圖。如果您使用表格視圖或垂直滾動​​滾動視圖,下面的代碼應該適合您。 44.0是示例代碼中表格單元格的高度,因此您需要將該值調整爲單元格的高度。如果用於水平滾動滾動視圖,請將y交換爲x,然後將44.0更改爲滾動視圖中各個分部的寬度。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    // Determine which table cell the scrolling will stop on. 
    CGFloat cellHeight = 44.0f; 
    NSInteger cellIndex = floor(targetContentOffset->y/cellHeight); 

    // Round to the next cell if the scrolling will stop over halfway to the next cell. 
    if ((targetContentOffset->y - (floor(targetContentOffset->y/cellHeight) * cellHeight)) > cellHeight) { 
     cellIndex++; 
    } 

    // Adjust stopping point to exact beginning of cell. 
    targetContentOffset->y = cellIndex * cellHeight; 
} 
+0

乾杯兄弟,我曾試着告訴他幾次。但我認爲他堅持自己的方法。 – Pavan

6

我強烈建議您使用 scrollViewWillEndDragging: withVelocity: targetContentOffset:方法,而不是爲了達到您的目的。將目標內容偏移量設置爲您想要的位置。

我也建議你看一下已經發布在SO上的重複問題。

Take a look at these posts

1

我相信,如果你使用的委託方法:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ 
    NSLog(@"%f",scrollView.contentOffset.y); 
    if (scrollView.contentOffset.y > 350 && scrollView.contentOffset.y < 370) 
    { 
     NSLog(@"setContentOffset"); 
     [scrollView setContentOffset:CGPointMake(0, 350) animated:YES]; 
    } 
} 

玩弄它,直到你獲得所需的行爲。 也許計算下一個tableViewCell/UIView的下一個上邊緣,並在最慢的一個頂端停下來。

原因是這樣的:if (scrollView.contentOffset.y > 350 && scrollView.contentOffset.y < 370)是滾動視圖調用scrollViewDidScroll在快速跳轉,所以我給了一個之間的if。

你也可以知道速度是放緩:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    NSLog(@"%f",scrollView.contentOffset.y); 
    int scrollSpeed = abs(scrollView.contentOffset.y - previousScrollViewYOffset); 
    previousTableViewYOffset = scrollView.contentOffset.y; 
    if (scrollView.contentOffset.y > 350 && scrollView.contentOffset.y < 370 && scrollSpeed < minSpeedToStop) 
    { 
     NSLog(@"setContentOffset"); 
     [scrollView setContentOffset:CGPointMake(0, 350) animated:YES]; 
    } 
} 
2

這裏的雨燕2.0相當於

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
    let cellWidth = CGRectGetWidth(frame)/7 // 7 days 
    var index = round(targetContentOffset.memory.x/cellWidth) 
    targetContentOffset.memory.x = index * cellWidth 
} 

而在長都爲你使用,而不是round這個複雜的舍入是沒有必要的floor

3

在雨燕2.0當表中有一個內容插入和簡化的東西,ninefifteen's great answer變成:

func scrollViewWillEndDragging(scrollView:   UIScrollView, 
           withVelocity velocity: CGPoint, 
           targetContentOffset: UnsafeMutablePointer<CGPoint>) 
{ 
    let cellHeight = 44 
    let y   = targetContentOffset.memory.y + scrollView.contentInset.top + cellHeight/2 
    var cellIndex = floor(y/cellHeight) 

    targetContentOffset.memory.y = cellIndex * cellHeight - scrollView.contentInset.top; 
} 

只需加上cellHeight/2即可,ninefifteen的if-不再需要增加索引的陳述。

3

如果您確實需要手動執行此操作,請使用Swift3版本。但是,強烈建議只打開UITableView的分頁,這已經爲您處理了。

let cellHeight = 139 
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
    targetContentOffset.pointee.y = round(targetContentOffset.pointee.y/cellHeight) * cellHeight 
} 

// Or simply 
self.tableView.isPagingEnabled = true 
相關問題