【问题标题】:iOS: Stretching / Resizing UITableView Header As The User Drags Down?iOS:在用户向下拖动时拉伸/调整 UITableView 标题的大小?
【发布时间】:2013-06-07 20:58:47
【问题描述】:

使用故事板,我在ViewController 中放置了一个imageView 作为我的tableView's headerView

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

根据用户正在查看的数据,viewController 将显示或隐藏headerView。我的问题是,当headerView 可见并且用户向下拖动tableView 时,我怎样才能让imageView 在调整大小时同时保持navigationBartableView覆盖中间的空间?

这是它目前所做的:

但这就是我想要的:

任何帮助将不胜感激。我看过视差库,但没有一个支持 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,由于某种原因,当我向下拖动时, 图像向上移动(就像导航栏后面的一半)并且不会返回。任何建议都是 不胜感激!!谢谢!

【问题讨论】:

  • 你找到解决办法了吗

标签: ios objective-c uitableview uiscrollview uiimageview


【解决方案1】:

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

这里是链接:Creating parallax effect on UIScrollView using constraints

【讨论】:

  • 这确实很棒,但对@KingPolycon 没有用,因为他在表格视图的顶部使用图像,在这种情况下处理起来要棘手得多-我自己还在研究。虽然我猜他要么找到了一种方法来做到这一点,要么在他发布这个问题后彻底改变了他的方法:p。
  • @Cyber​​Dandy 你是对的,表格视图标题视图的行为确实不同
  • 这就是人们应该与链接一起回答的原因。链接已失效。我将对此投反对票。这是一个 7 票,现在一文不值。当链接恢复或添加某种答案时,我会再次投票。
  • 用链接发帖是对的,但是如果你真的需要它,你可以去:web.archive.org/web/20160326225445/http://…
  • OP 要求提供表格标题视图,您的答案并不完全相关
【解决方案2】:

首先,您应该从标题中删除UIImageView,并将其作为简单的UIImageView 添加到UITableView 之上,然后由于UITableViewDelegate 协议符合UIScrollViewDelegate 协议,您可以实现@987654326 @ 方法检查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。另外我认为这个实现会产生弹跳效果,但我不确定,因为我现在无法测试它,但我认为这对你来说是一个很好的起点。

【讨论】:

  • 嗨,丹妮,感谢您抽出宝贵时间!我听从了您的建议,并尝试了您的建议。但是由于某种原因,当我向下拖动时,图像就消失了,再也没有回来。弹跳效果是我喜欢的。有什么建议?我已经更新了我的问题,向您展示我的尝试。
  • 请检查`initialFrame.size.height -= scrollView.contentOffset.y;`我认为有+ instad - 但我不确定。因此,首先检查scrollViewDidScroll 中的图像视图框架,然后检查是否需要在imageView 上使用setNeedsDisplay 来重绘图像。
  • @user1886754 查看我的评论
  • 数学不正确,这会使它看起来很生涩,因为它会不断增加越来越大的数字而不是增量。
【解决方案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,那就更漂亮了

【讨论】:

  • 还需要为表格视图设置清晰的背景色:)
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    当我需要将其与部分标题和索引栏一起使用时,此页面上的早期解决方案给我带来了一些麻烦,因此我自己想出了以下替代方案。请注意;我的项目中没有使用自动布局,我只在 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。只要您确保表格有一个清晰的彩色标题视图,其高度与您所需的标题相同,因为这可以作为一个分隔符,使您的单元格和部分标题保持一致。

    编辑:

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

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

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

    【讨论】:

      【解决方案6】:

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

      将您的滚动代理设置为 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 
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-29
        相关资源
        最近更新 更多