NSIndexPath用于当前tableview位置

时间:2015-01-13 07:04:48

标签: ios scrollview nsindexpath

我目前正在尝试模拟网站锚标签,以快速导航到浏览器页面上的特定点。我有一个分段控件作为超链接,如果你愿意的话。见下图:

image1

随着我的tableview部分和行的增长,这将成为用户使用的快速工具,特别是对于较小的设备。然而,我将滚动点与第一个单元格位置相等,但是我确实遇到了部分标题位置。

我的目标是在点击(简单部分)以及滚动(pickle部分)时更新segmentControl.selectedSegmentIndex,以便它更流畅的UI交互。

我已设置selectedSegmentIndex以使用NSIndexPaths IBAction来滚动浏览特定部分:

NSIndexPath *aboutIndex = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *contactIndex = [NSIndexPath indexPathForRow:0 inSection:1];
NSIndexPath *publicationsIndex = [NSIndexPath indexPathForRow:0 inSection:2];
NSIndexPath *settingsIndex = [NSIndexPath indexPathForRow:0 inSection:3];

switch (self.segmentControl.selectedSegmentIndex)
{
    case 0: [self.tableView scrollToRowAtIndexPath:aboutIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];
        break;
    //etc etc
    ...

使用相同的代码,我将它放在scrollViewDidScroll:方法中,就像您期望的那样,但我很难获得当前tableView滚动点的特定indexPath。我首先尝试了这个以及[self.tableView indexPathsForVisibleRows]:

 -(void)scrollViewDidScroll:(UIScrollView *)scrollView {

    NSIndexPath *currentIndex = [self.tableView indexPathForRowAtPoint:CGPointMake(0, self.tableView.contentOffset.y)];
    NSLog(@"current is %@", currentIndex);

    //And then changing the selectedSegmentIndex on scroll:

    if ((currentIndex >= aboutIndex) && (currentIndex < contactIndex)) {
        self.segmentControl.selectedSegmentIndex = 0;
    // other else if's
    ...
}

有时它会工作,当它基本上想要,并且只有在向下滚动时,我在手动向上滚动时才会为空。所以我把它改成了:

if ([currentIndex isEqual:aboutIndex]) {
    self.segmentControl.selectedSegmentIndex = 0;
} else if ([currentIndex isEqual:contactIndex]) {
    self.segmentControl.selectedSegmentIndex = 1;
} else if ([currentIndex isEqual:publicationsIndex]) {
    self.segmentControl.selectedSegmentIndex = 2;
} else if ([currentIndex isEqual:settingsIndex]) {
    self.segmentControl.selectedSegmentIndex = 3;
}

除了向上滚动外,它始终有效。我为什么要空滚动?

2 个答案:

答案 0 :(得分:1)

要回答您的上一个问题(“有人知道如何获取部分标题的来源吗?”),UITableView有一个方法- (CGRect)rectForSection:(NSInteger)section将返回该部分的CGRect。请参阅文档:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/index.html

由于标题应位于该部分的顶部,您应该能够使用rect的原点作为标题的原点(当然可能需要考虑文本插入)

或者,您也可以使用- (CGRect)rectForHeaderInSection:(NSInteger)section,因为顶部坐标应该相同。

当然,您可以将其与滚动位置进行比较,以获得CGRect s的相对屏幕位置。

答案 1 :(得分:0)

经过大量的游戏,我真的希望这是一个优雅的&amp;流畅的外观,我发现了一个更好的解决方案而不是jn_pdx。虽然他的答案是足智多谋并且朝着正确的方向,但我确实以这种方式尝试,并为这些部分创建了CGRects,但我发现滚动到- (CGRect)rectForSection:(NSInteger)section的唯一可行方式是[self.tableView scrollRectToVisible:animated:],当执行它时这样,rect直接滚动直到它可见,因此当向下滚动它时,它会起作用,因为它将tableView的最顶层部分带到可见的位置,在这种情况下恰好是屏幕的顶部,但滚动时,它滚动矩形直到它可见,最终在屏幕的底部(不希望的效果),因为这是它变得可见的第一个点。所以相反,我决定保留NSIndexPath方法和引用。我通过实现以下

来实现这一目标

点击segmentedControl

- (IBAction)segmentIndexChanged:(id)sender {

//Created the NSIndexPaths for all the sections 1st cells
NSIndexPath *aboutIndex = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *contactIndex = [NSIndexPath indexPathForRow:0 inSection:1];
NSIndexPath *publicationsIndex = [NSIndexPath indexPathForRow:0 inSection:2];
NSIndexPath *settingsIndex = [NSIndexPath indexPathForRow:0 inSection:3];

    //Scroll to the top most part of the cell
    switch (self.segmentControl.selectedSegmentIndex)
    {
    case 0:
        [self.tableView scrollToRowAtIndexPath:aboutIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];
        break;
    case 1:
        [self.tableView scrollToRowAtIndexPath:contactIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];
        break;
    case 2:
        [self.tableView scrollToRowAtIndexPath:publicationsIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];
        break;
    case 3:
        [self.tableView scrollToRowAtIndexPath:settingsIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];
        break;
    default:
        break; 
    } 
}

然后当UITableView被手动滚动时,我通过直接关联它在点击时滚动到的NSIndexPath来更新selectedSegmentIndex

滚动UITableView

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {

//Created a rect correlating to the tapped Index Paths
CGRect aboutRect = [self.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
CGRect contactRect = [self.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]];
CGRect publicationsRect = [self.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:2]];
CGRect settingsRect = [self.tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:3]];
//Get the current table view contentOffset point in CGRect form instead of CGFloat
CGRect scrollY = CGRectMake(0, self.tableView.contentOffset.y, self.tableView.bounds.size.width, self.tableView.bounds.size.height);
// NSLog current y point
NSLog(@"scrollY %@", NSStringFromCGRect(scrollY));

//Catch the intersecting points with CGRectContainsRect not CGRectEqualToRect
    if (CGRectContainsRect(scrollY, aboutRect)) {
        self.segmentControl.selectedSegmentIndex = 0;
    } else if (CGRectContainsRect(scrollY, contactRect)) {
        self.segmentControl.selectedSegmentIndex = 1;
    } else if (CGRectContainsRect(scrollY, publicationsRect)) {
        self.segmentControl.selectedSegmentIndex = 2;
    } else if (CGRectContainsRect(scrollY, settingsRect)) {
        self.segmentControl.selectedSegmentIndex = 3;
    }
}

它完美无瑕地工作一贯