iOS:在用户拖拽时拉伸/调整UITableView标头的大小?

使用storyboard,我在ViewController放置了imageView headerView作为我的tableView's headerView

这就是我的故事板设置方式:

在此处输入图像描述

根据用户正在查看的数据, viewController将显示或隐藏headerView 。 我的问题是,当headerView可见并且用户在tableView上向下拖动时, 如何调整使用headerView同时指向navigationBartableView以调整其间的空间?

这就是它目前的作用:

在此处输入图像描述

但这就是我想要的:

在此处输入图像描述

任何帮助将不胜感激。 我看过视差库,但是没有人支持sectionTitles,我也不一定会选择视差效果。 当用户向上滚动时,我希望它弹回到regularView而不是隐藏headerView。 谢谢!

更新:

我已经按照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后面的一半)并且不返回。 任何建议将不胜感激!! 谢谢!

我最近发布了一篇关于使用可能有所帮助的约束来完成此事的博客文章,结果certificate它非常直接。

这是链接: 使用约束在UIScrollView上创建视差效果

首先,您应该从头部删除UIImageView并将其作为简单的UIImageView添加到UITableView之上,然后由于UITableViewDelegate协议符合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; } } 

还要确保为UIImageView设置正确的contentMode 。 另外我认为这个实现会产生弹跳效果,但我不确定,因为我现在无法测试它,但我认为这对你来说是一个很好的起点。

这就是我实现它的方式,在我的情况下,我使用的是顶部的地图视图:

  1. 在故事板中创建视图控制器。
  2. 添加表视图并从所有方面将约束设置为0。
  3. 在表格视图下方添加地图视图(或任何视图),以便在顶部渲染。 看起来它会重叠。
  4. 在左上角和右上角添加约束。
  5. 在视图控制器viewDidLoad添加以下内容: tableView.contentInset = UIEdgeInsetsMake(200, 0, 0, 0)其中200是视图的高度。 这将向下推送表格视图的内容。
  6. 在视图控制器中添加以下代码,该代码基于滚动调整视图大小:

     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 ,那就更漂亮了

请看一下这个https://github.com/matteogobbi/MGSpotyViewController ,它可以根据您的要求实现相同的效果。

这个页面上的早期解决方案给我带来了一些麻烦,当我需要它与章节标题和索引栏一起工作时,所以我自己提出了以下替代方案。 请注意; 我在我的项目中没有使用autolayout而且我只在iOS9 +上测试过这个;

在您项目的故事板中:

  1. 在UIViewController中创建一个UITableView(或者使用UITableViewController尝试)。
  2. 将UIView放在UITableView的顶部(但在其中),因此它成为第一个单元格上方的表头。
  3. 为此标题视图指定所需的高度(例如200px),并将背景颜色设置为“清除颜色”。 清除颜色很重要,视图需要透明。
  4. 在表头UIView中删除第二个UIView,并使其大小与其父级相同。 这将是实际的标题,所以随意给它任何颜色,设置图像视图或其他内容。
  5. 将第二个UIView连接到你的UIViewController IBOutlet,我把它命名为“headerView”。

接下来,转到您的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。 只要确保表格的“清除彩色”标题视图集与所需标题的高度相同,因为这可以作为间隔符来保持单元格和节标题的一致性。

编辑:

我找到了一种更清洁的方法来实现这一目标;

  1. 如上所述在界面构建器中构建表头:1 UIView作为容器,其中嵌入了第二个UIView。
  2. 跳过上面的viewDidLoad代码,不需要将UIView拉出它的容器,我们不需要将它设置为表格背景。
  3. 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; } } 

而已。 只有与其他解决方案的视觉差异在于,内容现在将与其余单元格一起向上滚动,而不是与它们重叠。

我不知道,如果这对你有帮助..

将您的滚动委托设置为self。

然后实现这个:

 -(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 } }