如何使原生UIPageControl在50+页面下仅显示5-7个点且当前页居中
用原生UIPageControl实现“固定显示5-7个点,当前页居中”的效果
嘿,这个需求我太熟了!原生UIPageControl虽然没有直接的“固定显示中间N个点”的开关,但咱们分两种情况(iOS 14+ 和 更早版本)来实现,完全不用自定义UIView,纯原生搞定~
一、iOS 14 及以上版本(推荐)
iOS 14给UIPageControl加了个非常实用的属性:preferredNumberOfVisiblePages,直接设置它就能让控件自动控制可见的点数量,而且会把当前页的点保持在中间区域,刚好符合你要的Instagram效果!
实现步骤:
- 初始化UIPageControl并设置基础样式:
let pageControl = UIPageControl() pageControl.numberOfPages = 50 // 你的真实总页数 pageControl.currentPageIndicatorTintColor = .systemBlue pageControl.pageIndicatorTintColor = .lightGray
- 设置想要显示的可见点数量(比如5或7):
pageControl.preferredNumberOfVisiblePages = 5
- 关联UIScrollView的滚动事件,更新当前页码:
// 监听滚动视图的滚动,更新pageControl的当前页 func scrollViewDidScroll(_ scrollView: UIScrollView) { let currentPage = Int(scrollView.contentOffset.x / scrollView.bounds.width) pageControl.currentPage = currentPage }
设置完成后,当总页数超过5时,UIPageControl会自动只显示当前页附近的5个点,并且把当前页的点保持在中间位置,滚动时会平滑切换显示的点范围,完全就是你要的效果!
二、iOS 13 及更早版本(兼容旧系统)
旧系统没有preferredNumberOfVisiblePages属性,咱们得手动模拟这个逻辑,核心思路是:让UIPageControl只显示固定数量的点,通过计算相对页码来让当前页的点始终在中间。
实现步骤:
- 先定义几个关键常量:
let totalRealPages = 50 // 你的真实总页数 let visiblePageCount = 5 // 要显示的点数量 let middleIndex = visiblePageCount / 2 // 中间点的索引(5的话就是2)
- 初始化UIPageControl时,把
numberOfPages设为可见点数量:
let pageControl = UIPageControl() pageControl.numberOfPages = visiblePageCount pageControl.currentPageIndicatorTintColor = .systemBlue pageControl.pageIndicatorTintColor = .lightGray // 初始页为0时,让中间点先高亮 pageControl.currentPage = middleIndex
- 监听滚动事件,动态调整UIPageControl的显示逻辑:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { let realCurrentPage = Int(scrollView.contentOffset.x / scrollView.bounds.width) updatePageControl(with: realCurrentPage) } func updatePageControl(with realCurrentPage: Int) { var displayCurrentPage = middleIndex // 情况1:真实页码小于中间索引,直接显示对应位置的点 if realCurrentPage <= middleIndex { displayCurrentPage = realCurrentPage } // 情况2:真实页码接近末尾,显示最后几个点 else if realCurrentPage >= totalRealPages - middleIndex { displayCurrentPage = visiblePageCount - (totalRealPages - realCurrentPage) } // 情况3:中间区域,始终让中间点作为当前页指示器 else { displayCurrentPage = middleIndex } pageControl.currentPage = displayCurrentPage }
这种方式用固定数量的点模拟相对页码,首尾区域高亮点随真实页码移动,中间区域保持中间点高亮,用户能清晰感知当前位置,完全基于原生控件实现。
额外补充:
如果需要支持点击UIPageControl跳转页面,还得额外处理点击事件:根据当前显示的相对页码,计算出真实的目标页码,再让UIScrollView滚动到对应位置。
内容的提问来源于stack exchange,提问作者Marat Appleseed
相关产品推荐
相关产品推荐

