使用情节提要,我在imageView
内放置了tableView's
headerView
ViewController
。
这就是我的故事板设置方式:
根据用户查看的数据,viewController
会显示或隐藏headerView
。我的问题是,当headerView
可见并且用户拖放tableView
时,如何让imageView
坚持navigationBar
和tableView
调整大小以覆盖其间的空间?
这就是它目前所做的:
但这就是我想要的:
非常感谢任何帮助。我看过视差库,但是没有人支持sectionTitles,我也不一定会选择视差效果。当用户向上滚动时,我希望它弹回到regularView而不是隐藏headerView。谢谢!
UPDATE:
我已经按照下面Dany发布的建议完成了 以下内容:
-(void)scrollViewDidScroll:(UIScrollView*)scrollView { CGRect initialFrame = CGRectMake(0, 0, 320, 160); if (scrollView.contentOffset.y < 0) { initialFrame.size.height =! scrollView.contentOffset.y; childHeaderView.frame = initialFrame; } }
childHeaderView是一个imageView,出于某种原因,当我向下拖动时, 图像向上移动(就像在navBar后面的一半)并且不会返回。任何建议都是 非常感激!!谢谢!
答案 0 :(得分:7)
我最近发布了一篇关于使用可能有所帮助的约束来完成此事的博客文章,结果证明它非常直接。
以下是链接:Creating parallax effect on UIScrollView using constraints
答案 1 :(得分:5)
首先,您应该从标头中删除UIImageView
,并将其作为简单的UIImageView
添加到UITableView
之上,然后UITableViewDelegate
协议符合{{ 1}}协议,您可以实施UIScrollViewDelegate
方法来检查scrollViewDidScroll:
向下滚动并具有tableView
效果的时间。像这样的东西:
bouncing
另外,请务必为-(void)someInitMethod {
initialFrame = yourHeaderView.frame;
}
-(void)scrollViewDidScroll:(UIScrollView*)scrollView {
if(scrollView.contentOffset.y < 0) {
initialFrame.size.height -= scrollView.contentOffset.y;
yourHeaderView.frame = initialFrame;
}
}
设置正确的contentMode
。另外我认为这个实现会产生弹跳效果,但我不确定,因为我现在无法测试它,但我认为这对你来说是一个很好的起点。
答案 2 :(得分:2)
这就是我实现它的方式,在我的情况下,我使用的是顶部的地图视图:
viewDidLoad
中添加以下内容:tableView.contentInset = UIEdgeInsetsMake(200, 0, 0, 0)
其中200
是视图的高度。这将向下推送表格视图的内容。在视图控制器中添加以下代码,根据滚动调整视图大小:
func scrollViewDidScroll(scrollView: UIScrollView) {
var scrollOffset = scrollView.contentOffset.y
var headerFrame = mapView.frame
if (scrollOffset < 0) {
// Adjust map
headerFrame = CGRect(x: mapView.frame.origin.x,
y: mapView.frame.origin.y,
width: mapView.frame.size.width,
height: -scrollOffset)
} else {
// Adjust map
headerFrame = CGRect(x: mapView.frame.origin.x,
y: mapView.frame.origin.y,
width: mapView.frame.size.width,
height: 0)
}
mapView.frame = headerFrame
}
如果我可以从故事板中设置contentInset
,那将更加漂亮
答案 3 :(得分:1)
请查看此https://github.com/matteogobbi/MGSpotyViewController,其效果与您的要求相同。
答案 4 :(得分:1)
这个页面上的早期解决方案给我带来了一些麻烦,当我需要它与章节标题和索引栏一起工作时,所以我自己想出了以下替代方案。请注意;我没有在我的项目中使用自动布局,而且我只在iOS9 +上测试了这个;
在您项目的故事板中:
接下来,转到您的UIViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Remove view from table header and place it in the background instead.
[self.headerView removeFromSuperview];
UIView *backgroundView = [UIView new];
[backgroundView addSubview:self.headerView];
self.tableView.backgroundView = backgroundView;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
/* Set initialScrollOffset ivar to start offset, because in my case
the scroll offset was affected by the statusbar + navigation bar heights
and the view controller's "extend edges under top bars" option. */
initialScrollOffset = self.tableView.contentOffset.y;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
/* Modify headerView height only if the table content gets pulled
beyond initial offset. */
if (scrollView.contentOffset.y < initialScrollOffset) {
CGRect frame = self.headerView.frame;
frame.size.height = self.tableView.tableHeaderView.frame.size.height + -scrollView.contentOffset.y;
self.headerView.frame = frame;
}
}
我只需要为具有背景颜色和标签的拉伸标题实现此实现。不过,在这个标题中添加UIImageView应该很容易。
此外,步骤1至5当然是完全可选的。您可以以编程方式创建标题视图或使用XIB。只要您确保表格的“清除彩色”标题视图设置的高度与所需标题的高度相同,因为这可以作为间隔符来保持单元格和节标题符合标准。
修改强>
我找到了一种更清晰的方法来实现这一目标;
viewDidLoad
代码,无需将UIView从其容器中拉出来,我们也不需要将其设置为表格背景。scrollViewDidScroll:
方法更改为:<强> UIViewController.m:强>
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y < initialScrollOffset) {
CGRect frame = self.headerView.frame;
frame.size.height = self.tableView.tableHeaderView.frame.size.height - scrollView.contentOffset.y;
frame.origin.y = self.tableView.tableHeaderView.frame.origin.y + scrollView.contentOffset.y;
self.headerView.frame = frame;
}
}
那就是它。只有与其他解决方案的视觉差异在于,内容现在将与其他单元格一起向上滚动,而不是由它们重叠。
答案 5 :(得分:0)
我不知道,这是否会对你有所帮助..
将您的滚动委托设置为自己。
然后实现这个:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
float scrollViewHeight = scrollView.frame.size.height;
float scrollContentSizeHeight = scrollView.contentSize.height;
float scrollOffset = scrollView.contentOffset.y;
if (scrollOffset == 0)
{
// then we are at the top
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
// then we are at the end
// Do what you need here
}
}