ios UIScrollView 以编程方式设置 contentOffset 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6337233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:21:02  来源:igfitidea点击:

UIScrollView programmatically set contentOffset problem

iphoneiosuiscrollview

提问by Mike

I am creating an ImageViewer similar to the Photos app. I have a PagingScrollView that is the view of a view controller (created in loadView). The pages are UIScrollViews with UIImageView subviews. Everything works hunky dory until I try to 'skip' (set content offset) to an index besides the first one. If I skip to say, image 'i', the image is correctly displayed but if the user performs a single tap gesture the contentOffset resets itself back to display image '0'. The error does not happen with other gestures such as drag and it does not happen with touch if you do another gesture like drag first.

我正在创建一个类似于照片应用程序的 ImageViewer。我有一个 PagingScrollView,它是视图控制器的视图(在 loadView 中创建)。这些页面是带有 UIImageView 子视图的 UIScrollViews。一切正常,直到我尝试“跳过”(设置内容偏移)到第一个索引之外的索引。如果我跳过说图像“i”,则图像正确显示,但如果用户执行单击手势,则 contentOffset 将自身重置为显示图像“0”。其他手势(例如拖动)不会发生该错误,如果您先执行其他手势(例如拖动),则触摸不会发生该错误。

This is my loadView of the ImageViewerController

这是我的 ImageViewerController 的 loadView

- (void)loadView
{
    //Make the outer spaging scroll view
    CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
    scrollView.pagingEnabled = YES;
    scrollView.backgroundColor = [UIColor blackColor];
    scrollView.showsVerticalScrollIndicator = NO;
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.contentSize = [self contentSizeForPagingScrollView];
    scrollView.delegate = self;
    self.view = scrollView;
}

This is how I'm trying to set the content offset

这就是我尝试设置内容偏移的方式

#define myView (UIScrollView *)self.view

[myView setContentOffset:[self contentOffsetForIndex:index]];

[..]

- (CGPoint)contentOffsetForIndex:(NSUInteger)index
{
    return CGPointMake((index * (self.view.frame.size.width)), 0);
}

回答by Tatvamasi

Are you scrolling horizontally or vertically ? your offset logic
CGPointMake((index * (self.view.frame.size.width)), 0);is will move to 0 of Y axis. EDIT
I was a litte lazy writing the approach.
Here is the approach i adopt to find offset related issues:

你是水平滚动还是垂直滚动?您的偏移逻辑
CGPointMake((index * (self.view.frame.size.width)), 0);将移动到 Y 轴的 0。 编辑
我有点懒惰写方法。
这是我用来查找偏移相关问题的方法:

a) programmatically offset is set by setContentOffset:, scrollRectToVisible, setFrame(of UIScrollView, internally calls SetContentOffset). First check all of these in your code, if they are correct.

a) 以编程方式设置偏移量由 setContentOffset:, scrollRectToVisible, setFrame(of UIScrollView, 内部调用 SetContentOffset) 设置。首先检查代码中的所有这些,如果它们是正确的。

b) print the Logs for offset being set in scrollViewDidScroll:method.

b) 打印scrollViewDidScroll:方法中设置的偏移量的日志。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSLog(@" Offset = %@ ",NSStringFromCGPoint(scrollView.contentOffset));
}

This will help you identify the offset values being set (in most cases, the required offset is overriden by another call to setContentOffset: , some where in the code; lets say the current offset is (130,0) and you want to set the offset (300,0) it happens in steps (if animated) , you might get logs like
Offset = {130,0}
Offset = {190,0}
Offset = {220,0}
Offset = {270,0}
Offset = {300,0}

这将帮助您识别正在设置的偏移值(在大多数情况下,所需的偏移被另一个 setContentOffset: 调用覆盖,在代码中的某些位置;假设当前偏移是 (130,0) 并且您想要设置offset (300,0) 它分步发生(如果动画),你可能会得到类似的日志
Offset = {130,0}
Offset = {190,0}
Offset = {220,0}
Offset = {270,0}
Offset = {300,0}

If there is some other call to setContentOffset(animated), lets say it sets offset to (0,0), the logs you get would look like
Offset = {130,0}
Offset = {190,0}
Offset = {90, 0}
Offset = {220,0}
Offset = {60,0}
Offset = {270,0}
Offset = {30,0}
Offset = {300,0}
Offset = {0,0}

If you notice the second pattern in Logs, you can be sure that there is some un intended call to setContentOffset.
3) Once you identify there is a call to unintended call to setContentOffset, try to find the source of it (setting breakpoint to setContentOffset might help), and can be addressed on a case to case basis. for ex:
_adjustContentOffsetIfNecessary, is an internal method called when frame is set for UIScrollView. This can be the reason (try applying previous offset after setting the frame).

如果有一些其他的调用setContentOffset(动画),可以说,它设置偏移(0,0),你会看起来像日志 如果您发现日志的第二图案,你可以肯定,有一些未预期调用 setContentOffset。 3) 一旦您发现有对 setContentOffset 的意外调用,请尝试找到它的来源(将断点设置为 setContentOffset 可能会有所帮助),并且可以根据具体情况进行处理。例如:, 是为 UIScrollView 设置 frame 时调用的内部方法。这可能是原因(尝试在设置框架后应用先前的偏移量)。
Offset = {130,0}
Offset = {190,0}
Offset = {90, 0}
Offset = {220,0}
Offset = {60,0}
Offset = {270,0}
Offset = {30,0}
Offset = {300,0}
Offset = {0,0}



_adjustContentOffsetIfNecessary

Hope this helps (mee too , in getting the down vote removed :) )

希望这会有所帮助(我也是,在删除否决票方面:))

回答by Jeffrey Monte

I have the same problem(kinda) but my solution to my problem was that I disabled the

我有同样的问题(有点)但我的问题的解决方案是我禁用了

pagingEnabled 

of the UIScrollView... When your UIScrollview is resetting to a specific place when setting ContentOffset, please check that your pagingEnabled is disabled...

的 UIScrollView... 当您的 UIScrollview 在设置 ContentOffset 时重置到特定位置时,请检查您的 pagingEnabled 是否已禁用...