我目前正在尝试模拟网站锚标签,以快速导航到浏览器页面上的特定点。我有一个分段控件作为超链接,如果你愿意的话。见下图:
随着我的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;
}
除了向上滚动外,它始终有效。我为什么要空滚动?
答案 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;
}
}
它完美无瑕地工作一贯