在任何给定时间给定一个具有单个可见单元格的UITableView,如何在滚动表格视图时确定哪个单元格最多?
我知道通过这样做可以获得一系列可见细胞:
NSArray *paths = [tableView indexPathsForVisibleRows];
然后通过执行以下操作获取最后一个单元格(或第一个或其他单元格):
UITableViewCell* cell = (UITableViewCell*)[tableView cellForRowAtIndexPath:[paths lastObject]];
但是如何比较所有可见细胞并确定它们中哪一个最为可见?
答案 0 :(得分:4)
以下逻辑将为您提供滚动结尾处最明显的单元格:
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
CGRect visibleRect = (CGRect){.origin = self.tableView.contentOffset, .size = self.tableView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
NSIndexPath *visibleIndexPath = [self.tableView indexPathForRowAtPoint:visiblePoint];
}
答案 1 :(得分:3)
根据您返回的路径数量,算法会有所不同:
* 中点位置是第二个单元格的底部。顶部和底部位置是表格视图的顶部和底部。
答案 2 :(得分:1)
基于@ Sebyddd的答案的快速解决方案:
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
scrollToMostVisibleCell()
}
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate{
scrollToMostVisibleCell()
}
}
func scrollToMostVisibleCell(){
let visibleRect = CGRect(origin: tableView.contentOffset, size: tableView.bounds.size)
let visiblePoint = CGPoint(x: CGRectGetMidX(visibleRect), y: CGRectGetMidY(visibleRect))
let visibleIndexPath: NSIndexPath = tableView.indexPathForRowAtPoint(visiblePoint)!
tableView.scrollToRowAtIndexPath(visibleIndexPath, atScrollPosition: .Top, animated: true)
}
答案 3 :(得分:0)
您可以使用表格视图的rectForRowAtIndexPath:
来获取每个可见单元格的框架,然后将它们(CGRectOffset
)偏移-contentOffset.y
以考虑滚动,然后将它们与表格视图的bounds
可以查看每个单元格在表格视图中的可见程度。
答案 4 :(得分:0)
以下逻辑将为您提供UITableViewCell,每当用户停止滚动时,UITableViewCell就会在UITableView中显示最为明显或最重要的位置。希望这种逻辑可以帮助某人。
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
if (isScrollingStart)
{
isScrollingStart=NO;
isScrollingEnd=YES;
[self scrollingStopped];
}
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (isScrollingStart)
{
isScrollingStart=NO;
isScrollingEnd=YES;
[self scrollingStopped];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
isScrollingStart=YES;
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
isScrollingStart=YES;
}
-(void)scrollingStopped
{
NSMutableArray* arrVideoCells=[NSMutableArray array];
NSLog(@"Scrolling stopped");
NSArray* arrVisibleCells=[self.tableTimeline visibleCells];
for (TimeLineCell* cell in arrVisibleCells)
{
if ([cell isKindOfClass:[TimeLineCellMediaVideo class]])
{
[arrVideoCells addObject:cell];
}
}
TimeLineCellMediaVideo* videoCell=[self getCellNearCenterOfScreen:arrVideoCells];
}
-(TimeLineCellMediaVideo*)getCellNearCenterOfScreen:(NSMutableArray*)arrCells
{
TimeLineCellMediaVideo* closetCellToCenter;
CGRect filterCGRect;
for (TimeLineCellMediaVideo* videoCell in arrCells)
{
if (arrCells.count==1)
closetCellToCenter= videoCell;
NSIndexPath* cellIndexPath=[self.tableTimeline indexPathForCell:videoCell];
CGRect rect = [self.tableTimeline convertRect:[self.tableTimeline rectForRowAtIndexPath:cellIndexPath] toView:[self.tableTimeline superview]];
if (closetCellToCenter)
{
CGRect intersect = CGRectIntersection(self.tableTimeline.frame, filterCGRect);
float visibleHeightFilterCell = CGRectGetHeight(intersect);
intersect = CGRectIntersection(self.tableTimeline.frame, rect);
float visibleHeightCurrentCell = CGRectGetHeight(intersect);
if (visibleHeightCurrentCell>visibleHeightFilterCell)
{
filterCGRect=rect;
closetCellToCenter= videoCell;
}
}
else
{
closetCellToCenter=videoCell;
filterCGRect=rect;
}
}
return closetCellToCenter;
}
答案 5 :(得分:0)
我做了以下操作来找到大多数可见单元格的indexPath,并且它正常工作。
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
guard let tableView = scrollView as? UITableView else {
return
}
let visibleHeights = tableView.visibleCells.compactMap { cell -> (indexPath: IndexPath, visibleHeight: CGFloat)? in
guard let indexPath = tableView.indexPath(for: cell) else {
return nil
}
let cellRect = tableView.rectForRow(at: indexPath)
let superView = tableView.superview
let convertedRect = tableView.convert(cellRect, to: superView)
let intersection = tableView.frame.intersection(convertedRect)
let visibleHeight = intersection.height
return (indexPath, visibleHeight)
}
guard let maxVisibleIndexPath = visibleHeights.max(by: { $0.visibleHeight < $1.visibleHeight })?.indexPath else {
return
}
print("maxVisibleIndexPath: \(maxVisibleIndexPath)")
}