29

使用情节提要,imageViewtableView's headerViewViewController.

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

在此处输入图像描述

根据用户正在查看的数据,viewController将显示或隐藏headerView. 我的问题是,当headerView是可见的并且用户向下拖动 时tableView我怎样才能imageView同时控制navigationBar和 ,tableView因为它调整大小以覆盖两者之间的空间?

这是它目前所做的:

在此处输入图像描述

但这就是我想要的:

在此处输入图像描述

任何帮助将不胜感激。我看过视差库,但没有一个支持 sectionTitles,而且我也不一定要使用视差效果。当用户向上滚动时,我希望它反弹回常规视图而不是隐藏 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,由于某种原因,当我向下拖动时,图像会向上移动(就像导航栏后面的一半)并且不会返回。任何建议将不胜感激!!谢谢!

4

6 回答 6

7

我最近发布了一篇关于使用约束来完成此任务的博客文章,这可能会有所帮助,事实证明这很简单。

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

于 2014-03-24T06:08:52.587 回答
5

首先,您应该UIImageView从标头中删除 并将其作为简单的添加UIImageView到 then 之上,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;
    }
}

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

于 2013-06-11T21:41:57.610 回答
3

这就是我实现它的方式,在我的例子中,我使用的是顶部的地图视图:

  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从情节提要中设置它会更漂亮

于 2015-08-15T03:13:57.817 回答
1

请查看此https://github.com/matteogobbi/MGSPotyViewController ,它根据您的要求实现相同的效果。

于 2015-07-23T07:59:45.860 回答
1

当我需要将其与部分标题和索引栏一起使用时,此页面上的早期解决方案给我带来了一些麻烦,因此我自己想出了以下替代方案。请注意; 我的项目中没有使用自动布局,我只在 iOS9+ 上测试过;

在项目的故事板中:

  1. 在 UIViewController 中创建 UITableView(或使用 UITableViewController 尝试)。
  2. 在 UITableView 顶部(但在内部)放置一个 UIView,使其成为第一个单元格上方的表头。
  3. 给这个标题视图一个所需的高度(例如 200 像素)并将背景颜色设置为“清除颜色”。清除颜色很重要,视图需要透明。
  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。只要您确保表格具有与所需标题相同的高度设置的 Clear Colored 标题视图,因为这可以用作保持单元格和节标题对齐的间隔。

编辑:

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

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

而已。与其他解决方案的唯一视觉区别是内容现在将与其余单元格一起向上滚动,而不是被它们重叠。

于 2016-06-11T05:16:16.117 回答
0

我不知道,这是否对你有帮助..

将您的滚动委托设置为 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 
    }
}
于 2013-07-04T09:18:21.677 回答