是的。我为你准备了一个绝妙的技巧。
与其让你的红色轮廓视图成为一个滚动视图,不如让它成为一个填充屏幕的普通 UIView。在该视图中布置您的滚动视图(表格视图)和图像视图,就像它们在您的插图中一样。
在所有其他滚动视图和图像视图上方放置一个填充根视图边界(即也填充屏幕)的滚动视图。将此视图的内容大小设置为要滚动的所有视图的总内容高度。换句话说,在所有其他视图之上有一个不可见的滚动视图,其内容大小高度是内部滚动视图(表格视图)内容大小高度 + 图像视图大小高度。
层次结构应如下所示:
然后,您使用非常高的内容大小制作的顶部滚动视图使其代表成为您的视图控制器。实施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;