2011-10-17 125 views
10

有沒有辦法讓UITableViews滾動單元格到單元格?也就是說,表視圖的頂部始終是UITableViewCell的頂部。強制UITableView滾動到單元格頂部

我嘗試了分頁標誌,但似乎滾動整個「頁面」。我只是希望細胞到細胞的滾動。

感謝

回答

20

UTTableViewUIScrollView一個子類,所以你可以使用scrollViewDidScroll方法重新排列滾動後您的TableView滾動位置。

您可以使用tableView.contentOffset來獲取當前滾動位置。通過將它分成一個有意義的數字,你可以得到哪個單元格在最上面。

int cellIndex = tableView.contentOffset/cellHegiht; 

或者你可以在中心這樣當前可見的單元格(上,下):

NSArray *indexPathsForVisibleRows = [tableView indexPathsForVisibleRows]; 
NSIndexPath *selectedIndexPath = [indexPathsForVisibleRows objectAtIndex:(indexPathsForVisibleRows.count/2)]; //this gets center cell 

計算應該由它的邊緣點擊頂部(或底部)的細胞後,可以糾正從小區邊緣的漂移致電:

[tableView scrollToRowAtIndexPath:selectedIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

可以使用UIScrollViewDelegate方法來激活捕捉。您可以在滾動動畫完成時或動畫仍在繼續時激活。這將產生不同的用戶交互,並且不能說一個是另一個更好。

但是,僅僅實現下面的方法,並沒有別的樣子會是我最喜歡的:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset { 
    int cellHeight = 41; 
    *targetContentOffset = CGPointMake(targetContentOffset->x, 
             targetContentOffset->y - (((int)targetContentOffset->y) % cellHeight)); 
} 

,當用戶在觸摸TableView最多通知應用程序調用此方法。 targetContentOffset是一個inout變量,因此您可以在動畫繼續時真正設置最終滾動位置。使用正確的cellHeight,您的TableView將始終捕捉到單元格。

+2

感謝您展示如何使用'inout'變量。非常好的功能! – Besi

+0

+1我也感謝你指出「inout」變量。 – jpswain

+0

隨着你的數學 - 你不能滾動到表中的最後一行...不是一個問題,但補救。 - 絕對是最好的解決方案。 – scottbates22

0

您只需調用scrollToRowAtIndexPath:atScrollPosition:animated:並將它傳遞給您想要的單元格的正確索引路徑即可。

1

雖然完全正確,但我沒有找到@randle的答案,非常有幫助。我閱讀了開發者文檔,而且我更加困惑。我終於發現答案是多麼簡單,但有時候我們需要一些幫助而不是「調用這個方法」。請參閱評論//滾動到行!在這裏:現在

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 
    if (textField == self.firstInput) { 
     [self.secondInput becomeFirstResponder]; 

     // scroll to row! 
     [self.tableView scrollToRowAtIndexPath: // use the method 
      [NSIndexPath indexPathForRow:1  // get 2nd row (nth row...) 
           inSection:0] // in 1st section (...) 
         // set position: you can use bottom, middle or top. 
         atScrollPosition:UITableViewScrollPositionBottom 
           animated:YES]; // YES or NO. 

    } else if (textField == self.secondInput) { 
     [textField resignFirstResponder]; 
    } 
    return YES; 
} 

,這是一個靜態細胞的tableView。我知道行數,我知道我要去哪一行。這可以擴展到更好的代碼,並以編程方式訪問變量,但它顯示瞭如何在低層次上實踐這些代碼。

我希望這會爲搜索論壇的任何人增加一層有用性。

我在這裏做的方法的完整的寫了起來:http://iosanswers.blogspot.com/2012/02/table-view-forms-scroll-to-selected.html

3

如果你有專門的章節,我發現這是最可靠的方法:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate(BOOL)decelerate { 
    if (decelerate == NO) { 
     [self autoAdjustScrollToTop]; 
    } 
} 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    [self autoAdjustScrollToTop]; 
} 
- (void)autoAdjustScrollToTop { 
    // compare the top two visible rows to the current content offset 
    // and auto scroll so that the best row is snapped to top 
    NSArray *visibleRows = [self.tableView indexPathsForVisibleRows]; 
    NSIndexPath *firstPath = visibleRows[0]; 
    NSIndexPath *secondPath = visibleRows[1]; 
    CGRect firstRowRect = [self.tableView rectForRowAtIndexPath:firstPath]; 
    [self.tableView scrollToRowAtIndexPath:(firstRowRect.origin.y > self.tableView.contentOffset.y ? firstPath : secondPath) atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 
1

這種方法處理具有不同行高度表視圖。它假設表格視圖有一個單獨的部分。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset { 

    // Find the row where the animation will currently end. 
    NSInteger targetRow = [[self.tableView indexPathForRowAtPoint:*targetContentOffset] row]; 

    // Tell the animation to end at the top of that row. 
    *targetContentOffset = [self offsetForTopOfRow:targetRow]; 
} 

偏移量通過此幫助程序方法計算,該方法將目標行上方所有行的高度相加。

- (CGPoint)offsetForTopOfRow:(NSInteger)row { 

    CGPoint offset = CGPointZero; 

    for (int i = 0; i < row; i++) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; 
     CGFloat height = [self.tableView.delegate tableView:self.tableView heightForRowAtIndexPath:indexPath]; 
     offset.y += height; 
    } 

    return offset; 
} 
0

如果您有具有靜態高度的部分和行,則此方法可行。

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
    // Adjust target offset so that cells are snapped to top 
    let cellHeight: CGFloat = 44 
    let headerHeight: CGFloat = 30 
    let section = (indexPathsForVisibleRows?.first?.section ?? 0) + 1 
    targetContentOffset.memory.y -= (targetContentOffset.memory.y % cellHeight) - (CGFloat(sectionIndex) * headerHeight) 
} 
相關問題