我在UITableView
中显示相当大的图像。当用户滚动时,我希望在桌面视图中始终将中心最多的照片捕捉到中间。也就是说,当桌子处于静止状态时,它将始终与中心对齐UITableViewCell
。
如何做到这一点?
答案 0 :(得分:29)
您可以使用UIScrollViewDelegate
上的UITableView
方法执行此操作:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
// if decelerating, let scrollViewDidEndDecelerating: handle it
if (decelerate == NO) {
[self centerTable];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self centerTable];
}
- (void)centerTable {
NSIndexPath *pathForCenterCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), CGRectGetMidY(self.tableView.bounds))];
[self.tableView scrollToRowAtIndexPath:pathForCenterCell atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
答案 1 :(得分:17)
尤其是UIScrollView委托方法!
当用户停止滚动时,表格视图(滚动视图)将调用- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
。您可以设置操作targetContentOffset
以确保它最终到达您想要的位置,并且它将在该位置结束减速(就像分页UIScrollView一样)。
例如,如果你的细胞都是100点高,你可以这样做:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
targetContentOffset->y = 100 * (int)targetContentOffset->y/100;
}
当然,您也可以检查传入的targetContentOffset
以查看它将要落地的位置,然后找到所在的单元并对其进行适当更改。
答案 2 :(得分:6)
扩展@ jesse-rusak上面的答案,如果您的单元格具有可变高度,那么这是您需要添加到UITableViewController子类的代码。这将避免在接受的答案中出现双滚动问题。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
NSIndexPath *pathForTargetTopCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), targetContentOffset->y)];
targetContentOffset->y = [self.tableView rectForRowAtIndexPath:pathForTargetTopCell].origin.y;
}
答案 3 :(得分:5)
根据@jszumski发布的内容构建,如果您希望在拖动过程中进行捕捉,请使用以下代码:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
[self centerTable];
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
[self centerTable];
}
- (void)centerTable {
NSIndexPath *pathForCenterCell = [self.tableView indexPathForRowAtPoint:CGPointMake(CGRectGetMidX(self.tableView.bounds), CGRectGetMidY(self.tableView.bounds))];
[self.tableView scrollToRowAtIndexPath:pathForCenterCell atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
答案 4 :(得分:1)
扩展@mikepj答案(反过来扩展了@JesseRusak的出色答案),即使单元格的高度可变(或未知),此代码也可以使您捕捉到单元格,并且如果您将滚动到该行的下半部分,使其更加“自然”。
原始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;
}
答案 5 :(得分:0)
快速偷看
override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
{
if decelerate == false
{
self.centerTable()
}
}
override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
self.centerTable()
}
func centerTable()
{
let midX:CGFloat = self.tableView.bounds.midX
let midY:CGFloat = self.tableView.bounds.midY
let midPoint:CGPoint = CGPoint(x: midX, y: midY)
if let pathForCenterCell:IndexPath = self.tableView .indexPathForRow(at: midPoint)
{
self.tableView.scrollToRow(at: pathForCenterCell, at: .middle, animated: true)
}
}//eom
答案 6 :(得分:-3)
UITableView扩展了UIScrollView ...
myTableView.pagingEnabled = YES