【发布时间】:2025-11-23 04:50:01
【问题描述】:
在我的滚动视图中,我想获取正在显示的当前页面(也许页面不是正确的术语)。我找不到任何包含这个的变量。但我认为它必须放在某个地方,因为指示器能够显示当前正在显示滚动视图的哪个子视图。
这是对我们完全隐藏还是有办法让我访问它?
【问题讨论】:
标签: ios objective-c iphone cocoa-touch uiscrollview
在我的滚动视图中,我想获取正在显示的当前页面(也许页面不是正确的术语)。我找不到任何包含这个的变量。但我认为它必须放在某个地方,因为指示器能够显示当前正在显示滚动视图的哪个子视图。
这是对我们完全隐藏还是有办法让我访问它?
【问题讨论】:
标签: ios objective-c iphone cocoa-touch uiscrollview
当前页面没有UIScrollView 属性。你可以计算它:
int page = scrollView.contentOffset.x / scrollView.frame.size.width;
如果要向上或向下舍入到最近的页面,请使用:
CGFloat width = scrollView.frame.size.width;
NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;
【讨论】:
UIScrollViewDelegate获取当前页面!
我非常推荐你使用这个代码
int indexOfPage = scrollView.contentOffset.x / scrollView.frame.size.width;
但是如果您使用此代码,您的视图不需要完全位于 indexOfPage 为您提供的页面上。 这是因为我也建议您仅在此方法中使用此代码
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{}
当你的 scrollView 完成滚动并让你的页面数量非常清晰时调用它
我建议您使用此代码将滚动视图设置为启用分页
[scrollView setPagingEnabled:YES];
所以最后应该是这样的
-(void) methodWhereYouSetYourScrollView
{
//set scrollView
[scrollView setPagingEnabled:YES];
scrollView.delegate = self;
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int indexOfPage = scrollView.contentOffset.x / scrollView.frame.size.width;
//your stuff with index
}
【讨论】:
我会在扩展中快速完成:
extension UIScrollView {
var currentPage:Int{
return Int((self.contentOffset.x+(0.5*self.frame.size.width))/self.frame.width)+1
}
}
然后只需调用:
scrollView.currentPage
【讨论】:
同上,但作为一个类别
@interface UIScrollView (CurrentPage)
-(int) currentPage;
@end
@implementation UIScrollView (CurrentPage)
-(int) currentPage{
CGFloat pageWidth = self.frame.size.width;
return floor((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
}
@end
【讨论】:
另一种方式:
extension MyViewController: UIScrollViewDelegate {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let width = scrollView.frame.width
let page = Int(round(scrollView.contentOffset.x/width))
print("CurrentPage:\(page)")
}
}
【讨论】:
这里已经有一些很好的答案。但是,对于内容不完全适合页面的情况 - 如果您像我一样想将结果用于UIPageControl,那么使用ceil 函数是必不可少的。
让我们举个例子,我有“四页”的内容。
我将基于我当前的现实生活示例。内容大小宽度为 3140 点。根据我的集合视图框架大小,页面宽度为 728。
所以页数等于:
3140 / 728 = 4.313
我的numberOfPages 将是五岁。其中四个将完整显示,最后一个 - 第 5 页 - 将显示剩余的 0.313 内容。
现在,numberOfPages 为 5 意味着页面索引将为 0、1、2、3 和 4。
当我向右滑动,向最终偏移量翻页时,scrollViewDidEndDecelerating 方法给出的最终 X 偏移量为 2412。
应用舍入计算:
2412 / 728 = 3.313 then rounded = 3
这是不正确的。页面用户正在查看的偏移量应该是:
Offset / Page User Is Viewing
0 0
728 1
1456 2
2184 3
2412 4
使用ceil的正确计算:
private func pageForOffset(offset:CGFloat, pageWidth width:CGFloat) -> Int
{
let page = Int(ceil(offset / width))
NSLog("\(__FUNCTION__) offset \(offset) width \(width) page \(page) ")
return page
}
【讨论】:
只需将当前偏移量除以页面大小即可:
CGFloat pageNum = (int)(scrollView.contentOffset.x / scrollView.frame.size.width);
【讨论】:
Aoakenfo 的解决方案很神奇,这是另一个结合你的代码和函数 scrollViewDidScroll 和 PageController 的解决方案
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (sender == self.scroll) {
int pageNum = (int)(self.scrPage.contentOffset.x / self.scrPage.frame.size.width);
self.pagecontroller.currentPage =pageNum;
}
}
【讨论】:
为了快速,我会使用这个
let width = scrollView.frame.width
let page = round(scrollView.contentOffset.x/width)
非常简单,它基本上取scrollview x 位置,除以scrollview 宽度,然后舍入。
【讨论】:
在 xCode 7.x swift 2.x 中你可以这样做:
//MARK: - ScrollView Extensions
// Get the current page number
extension UIScrollView {
var currentPage: Int {
return Int(round(self.contentOffset.x / self.bounds.size.width))
}
// If you have reversed offset (start from contentSize.width to 0)
var reverseCurrentPage: Int {
return Int(round((contentSize.width - self.contentOffset.x) / self.bounds.size.width))-1
}
}
【讨论】:
我从我们的几个应用程序中提取了这个...
- (NSInteger)currentPage
{
if (0 == self.frame.size.width) {
NSLog(@"frame width == 0!");
return 0;
}
if (! self.currentPageValid) {
_currentPage = round(self.contentOffset.x / self.frame.size.width);
self.currentPageValid = YES;
}
return _currentPage;
}
【讨论】:
您使用的是 UIPageControl 吗?如果是这样,这有一个currentPage 属性。如果没有,我认为您需要根据 scrollView 偏移量计算页面索引。
【讨论】:
Swift 5.1+ UIScrollView 扩展(省略 return 关键字)
extension UIScrollView {
var currentPage: Int {
Int(round(self.contentOffset.x / self.frame.width))
}
}
【讨论】:
如果有人在 C# 中寻找 Xamarin 的方法
public int CurrentIndex
{
get => (int)Math.Round(this.scrollView.ContentOffset.X / this.scrollView.Frame.Width);
set => this.scrollView.ScrollRectToVisible(new CGRect(new CGPoint(this.scrollView.Frame.Size.Width * value, 0), this.scrollView.Frame.Size), true);
}
这个 getter 和 Setter 应该为您提供当前页面以及让您滚动到指定页面
【讨论】: