是否可以在UITableView或UIScrollView中添加捕捉位置?我的意思是,如果我按下按钮或调用某种方法来自动滚动到某个位置,我的意思是如果我滚动滚动视图或桌面视图围绕特定点,比如0, 30
,它将自动 - 抓住它并留在那里?因此,如果我的滚动视图或表格视图滚动,然后用户放在0, 25
或0, 35
之间,它会自动“捕捉”并滚动到那里?我可以想象可能会输入一个if语句来测试UIScrollView的scrollViewDidEndDragging:WillDecelerate:
或scrollViewWillBeginDecelerating:
方法中该位置是否属于该区域但是我不确定如何在UITableView的。任何指导都将非常感谢。
答案 0 :(得分:24)
就像Pavan所说,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;
}
答案 1 :(得分:6)
我劝你用
相反,scrollViewWillEndDragging: withVelocity: targetContentOffset:
方法仅用于您的目的。将目标内容偏移设置为您想要的位置。
我还建议您查看已在SO上发布的重复问题。
答案 2 :(得分:3)
在Swift 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
,就不再需要使用九十九个if
语句来增加索引。
答案 3 :(得分: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
答案 4 :(得分:2)
这里是Swift 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
答案 5 :(得分: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];
}
}
答案 6 :(得分:0)
即使单元格的高度可变(或未知),此代码也可以使您捕捉到单元格,如果您滚动到该行的下半部分,则可以捕捉到下一行,从而使其更“自然”
原始Swift 4.2代码:(为方便起见,这是我开发和测试的实际代码)
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
guard var scrollingToIP = table.indexPathForRow(at: CGPoint(x: 0, y: targetContentOffset.pointee.y)) else {
return
}
var scrollingToRect = table.rectForRow(at: scrollingToIP)
let roundingRow = Int(((targetContentOffset.pointee.y - scrollingToRect.origin.y) / scrollingToRect.size.height).rounded())
scrollingToIP.row += roundingRow
scrollingToRect = table.rectForRow(at: scrollingToIP)
targetContentOffset.pointee.y = scrollingToRect.origin.y
}
(翻译的)Objective-C代码:(因为该问题被标记为objective-c
)
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
NSIndexPath *scrollingToIP = [self.tableView indexPathForRowAtPoint:CGPointMake(0, targetContentOffset->y)];
if (scrollingToIP == nil)
return;
CGRect scrollingToRect = [table rectForRowAtIndexPath:scrollingToIP];
NSInteger roundingRow = (NSInteger)(round(targetContentOffset->y - scrollingToRect.origin.y) / scrollingToRect.size.height));
scrollingToIP.row += roundingRow;
scrollingToRect = [table rectForRowAtIndexPath:scrollingToIP];
targetContentOffset->y = scrollingToRect.origin.y;
}