一个UIScrollView内的UIScrollView,如何保持一个平稳过渡两者之间滚动时(UIS

2019-07-03 13:33发布

我有以下布局(见下文),这对于大多数情况下工作得很好。 用户能够在蓝色中滚动UIScrollView (这对于所有意图和目的是UITableView ,但这个问题可以推广这一点),然后当他们已经达到这个滚动视图的结束,他们可以重新开始滚动(他们有把他们的手指关闭,再打开,因为内滚动视图橡皮筋其他方式),以及“超级”滚动视图开始滚动,揭示了图像的其余部分。

这是整个(他们必须把他们的手指离开,并再次打开,因为内滚动视图橡皮筋其它我不想。 理想的情况是,一旦所包含UIScrollView达到其内容的结束,我想上海华接手滚动直线距离,使内滚动视图不橡皮。

当用户滚动回升也是一样; 当红色滚动型达到它的顶部的内容,我想内的蓝色滚动视图开始马上向上滚动,而不是在顶部橡皮红滚动视图。

任何想法如何? 我能确定何时滚动的意见已达到其内容的目的,但我不知道如何运用这些知识来实现​​我追求的效果。 谢谢。

// Inner (blue) scroll view bounds checking
if (scrollView.contentOffset.y + scrollView.frame.size.height > scrollView.contentSize.height) { ... }

// Outer (red) scroll view bounds checking
if (scrollView.contentOffset.y < 0) { ... }

Answer 1:

是啊。 Ive得到了一个漂亮的把戏给你。

而不是你的红色轮廓图滚动型使它成为一个正常的UIView是充满屏幕。 在这一观点奠定了滚动视图(表视图)和图像查看,因为它们在你的插图。

放置填充根视图的所有其它滚动视图和图像视图上述边界(即还填充画面)的滚动视图。 设置此观点的内容大小是所有想要通过滚动视图的总含量高。 。换句话说也有看不见的滚动型坐在你的所有其他视图顶部,其含量大小高度内滚动视图(实现代码如下)含量大小高度+图像视图大小的高度。

该heierarchy应该是这样的:

然后,这个滚动视图顶部,你有那座内容大小制成使其代表是你的视图控制器。 实施scrollViewDidScroll我们将努力一些魔法。

Scrollviews基本上与动量和东西时髦公式调整范围起源滚动。 因此,在我们scrollviewDidScroll方法,我们将简单地调整的基本观点的界限:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

    //the scroll view underneath (in the container view) will have a max content offset equal to the content height
    //but minus the bounds height
    CGFloat maxYOffsetForUnderScrollView = self.underScrollView.contentSize.height - self.underScrollView.bounds.size.height;

    CGRect scrolledBoundsForContainerView = self.view.bounds;

    if (scrollView.contentOffset.y <= maxYOffsetForUnderScrollView) {
        //in this scenario we are still within the content for the underScrollView
        //so we make sure the container view is scrolled to the top and set the offset for the contained scrollview
        self.containerView.bounds = scrolledBoundsForContainerView;
        self.underScrollview.contentOffset = scrollView.contentOffset;
        return;
    }

    //in this scenario we have scrolled throug the entirety of the contained scrollview
    //set its offset to the max and change the bounds of the container view to scroll everything else.
    self.underScrollView.contentOffset = CGPointMake(0, maxYOffsetForUnderScrollView);

    scrolledBoundsForContainerView.origin.y = scrollView.contentOffset.y - maxYOffsetForUnderScrollView;
    self.containerView.bounds = scrolledBoundsForContainerView;
}

你会发现,当scrollViewDidScroll被称为动画的每一帧的包含该意见人造滚动看起来非常自然。

可是等等! 我听到你说。 顶部有滚动视图现在拦截所有的接触,并在其下方的观点需要被接触为好。 我有一个有趣的解决方案,以及。

设置在上面滚动视图是关闭屏幕的地方(即设置它的框架关闭屏幕,但仍然是相同的大小),然后在您viewDidLoad方法添加了滚动的panGestureRecogniser到主视图。 这将意味着你所有的iOS的自然滚动势头之类的东西,而不必实际屏幕上的视图。 所包含的滚动视图现在大概会颤抖作为其泛手势识别将被调用,以及(它们的工作方式不同,以处理的UIEvent),所以您需要将其删除。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self.view addGestureRecognizer:self.scrollview.panGestureRecognizer];

    [self.underScrollview removeGestureRecognizer:self.underScrollView.panGestureRecognizer];

    //further code to set up content sizes and stuff
}

我很开心使得这款因此,继承人在GitHub上的链接示例项目: https://github.com/joelparsons/multipleScrollers

编辑:

要显示顶部滚动视图时,它的关闭屏幕滚动条无论你在哪里把它,你可以设置scrollIndicatorInsets像这样创建的插图:

CGPoint scrollviewOrigin = self.scrollview.frame.origin;
self.scrollview.scrollIndicatorInsets = UIEdgeInsetsMake(-scrollviewOrigin.y,0,scrollviewOrigin.y,scrollviewOrigin.x);

*需要注意的是,滚动型仍然是正确的高度,但我敢肯定你的想法。

然后,使杆平局滚动视图的可见范围之外,你必须剪辑关掉界限

self.scrollview.clipsToBounds = NO;


文章来源: UIScrollView within a UIScrollView, how to keep a smooth transition when scrolling between the two