8

我使用 UIScrollView 作为我的分页滚动视图,pagesScrollView. 在其中,我放置了专门用于缩放的单个 UIScrollView。在其中的每一个中,我都有一个视图,它是应该可以缩放的页面项目。所有这些都在带有半透明导航栏的 UINavigationController 中。

我的pagesScrollViewcontentInset.top = 64bounds.origin.y = -64(这对我来说似乎很奇怪,但这是系统自动为我设置的),这很好用。我的屏幕看起来很棒!

但是,在我滚动pagesScrollView一点点之后,一旦scrollViewWillEndDragging被调用,就会pagesScrollView开始动画变化,bounds.origin.y = -64导致bounds.origin.y = 0我的页面项目被导航栏遮挡。

左边是加载时的样子,右边是我拖动几个像素然后松开后的样子,它在导航栏下向上滑动(因为bounds.origin.y变为0) .

在此处输入图像描述

问题是我没有任何更改边界的代码,并且在各种滚动委托方法中没有任何代码可以做任何事情。我添加了一堆滚动委托方法,并且刚刚添加了 NSLog()s,这样我就可以弄清楚更改发生的时间/地点,但它并没有在我的代码中的任何地方发生。

所以,我不知道我可以向你展示什么代码来帮助你帮助我。

编辑:我从头开始构建了一个新项目以删除所有其他变量。我将一个裸 UIViewController 放入 UINavigationController。我将一个 UIScrollView 放入我的视图中,整个视图的大小。以下代码是整个项目。

事实证明,问题(如下所述)仅在 UIScrollView 上启用 PAGING 时出现!什么?:)

这是一个下载一个基本项目的链接,它只有几行代码来演示这个问题。只需单击滚动视图,您就会看到它随着边界的变化而向上移动。http://inadaydevelopment.com/stackoverflow/WeirdScrollViews.zip

如何在滚动视图上启用分页,而不会在滚动和移动导航栏下的所有内容时出现边界?

可以将导航栏设置为不透明并避免问题,但理想的情况是具有标准的 iOS7 行为,以便在缩放内容视图后,允许内容位于导航栏下方,并且应该通过半透明正常显示。

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    NSArray *colors = @[
                        [UIColor blueColor],
                        [UIColor orangeColor],
                        [UIColor magentaColor],
                        ];

    NSArray *zoomerColors = @[
                        [UIColor greenColor],
                        [UIColor yellowColor],
                        [UIColor purpleColor],
                        ];


    self.scroller.pagingEnabled = YES;

    [self.scroller setContentSize:CGSizeMake(self.scroller.frame.size.width*colors.count, self.scroller.frame.size.height)];

    CGRect subviewFrame = CGRectMake(0, 0, 160, 240);
    for (int index=0; index < colors.count; index++) {
        UIColor *color = [colors objectAtIndex:index];
        UIColor *zoomerColor = [zoomerColors objectAtIndex:index];

        UIView *subview = [[UIView alloc] initWithFrame:subviewFrame];
        subview.backgroundColor = color;

        CGRect zoomerFrame = CGRectMake(index*self.scroller.frame.size.width, 0, self.scroller.frame.size.width, self.scroller.frame.size.height);

        UIScrollView *zoomer = [[UIScrollView alloc] initWithFrame:zoomerFrame];
        [zoomer addSubview:subview];
        zoomer.backgroundColor = zoomerColor;

        [self.scroller addSubview:zoomer];

    }
}
4

5 回答 5

16

只需关闭调整滚动视图插图

在此处输入图像描述

于 2014-05-12T11:43:01.227 回答
11

这是一个iOS错误。我创建了以下子类来获取随着时间的推移UIScrollView发生的事情以及谁在推动它的日志:y

@implementation CSScrollView

- (void)setContentOffset:(CGPoint)contentOffset
{
    NSLog(@"%0.0f %@", contentOffset.y, [NSThread callStackSymbols]);
    NSLog(@"[%@]", self.layer.animationKeys);
    [super setContentOffset:contentOffset];
}

@end

(并更改了情节提要中的视图类)

当您松开手指时,一个名为的方法UIScrollView _smoothScrollDisplayLink:开始将滚动视图动画化到其最终位置。根据第二个日志,没有CAAnimation涉及,滚动视图使用自己的显示链接进行自己的转换。该自定义代码似乎犯了动画 from y = whateverto的错误y = 0,没有考虑到内容偏移。

作为概念验证黑客,我将代码更改为:

@implementation CSScrollView

- (void)setContentOffset:(CGPoint)contentOffset
{
    contentOffset.y = -64.0f;
    [super setContentOffset:contentOffset];
}

@end

而且,不出所料,问题消失了。

您可能不想硬编码,-64.0f但我会得出结论:

  • 这是一个 iOS 错误;
  • 通过UIScrollView具有适当自定义实现的- setContentOffset:.

一个明智的通用方法可能是检查stateof self.panGestureRecognizer- 这将允许您区分用户负责的滚动和其他滚动,而无需依赖任何未记录的 API 或复杂的委托事件捕获。然后,如有必要,请contentOffset.y从当前值中删除正确的值,而不是对其进行硬编码。

于 2014-05-10T00:04:56.937 回答
0

我已经检查了您在 viewController.m 文件中使用以下代码的示例

-(void)viewDidLoad
{
    if ([[UIDevice currentDevice] systemVersion].floatValue>=7.0) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }
}

它工作正常...

于 2014-05-12T11:55:03.697 回答
0

我的 pagesScrollView 有 contentInset.top = 64 和 bounds.origin.y = -64 (这对我来说似乎很奇怪,但这是系统自动为我设置的),这很好用。我的屏幕看起来很棒!

这是因为 iOS 7 在所有滚动视图上将 contentInset.top 设置为 64。只需将这行代码添加到您的视图控制器中,一切都会按预期工作:

-(UIRectEdge)edgesForExtendedLayout {
return UIRectEdgeNone;

}

我检查了您的示例项目。

于 2014-05-09T15:56:35.803 回答
0

事实证明,问题(如下所述)仅在 UIScrollView 上启用 PAGING 时出现!什么?:)

正如您所说,如果您启用滚动分页,UIScrollView 将在拖动或任何移动后停止在分页边缘,这是框架承诺的。Bounds.origin.y 设置为零表示第一页边缘与滚动视图框架边缘匹配,因为那里有 64 个 contentInsets。所以这不是错误,就是这样。而且由于您的栏是半透明的,请记住滚动视图的框架边缘在哪里,它在栏下方。总之,我认为这不是错误,而是滚动分页的效果。

于 2020-05-14T06:43:33.607 回答