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

时间:2013-06-11 21:04:21

标签: ios objective-c uitableview uiscrollview uiimageview

使用情节提要,我在imageView内放置了tableView's headerView ViewController

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

enter image description here

根据用户查看的数据,viewController会显示或隐藏headerView。我的问题是,当headerView可见并且用户拖放tableView时,如何让imageView坚持navigationBartableView调整大小以覆盖其间的空间?

这就是它目前所做的:

enter image description here

但这就是我想要的:

enter image description here

非常感谢任何帮助。我看过视差库,但是没有人支持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后面的一半)并且不会返回。任何建议都是   非常感激!!谢谢!

6 个答案:

答案 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)

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

  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
    }
    
  7. 如果我可以从故事板中设置contentInset,那将更加漂亮

答案 3 :(得分:1)

请查看此https://github.com/matteogobbi/MGSpotyViewController,其效果与您的要求相同。

答案 4 :(得分:1)

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

在您项目的故事板中:

  1. 在UIViewController中创建一个UITableView(或者使用UITableViewController尝试)。
  2. 将UIView放在UITableView的顶部(但在其中),因此它成为第一个单元格上方的表格标题。
  3. 为此标题视图指定所需的高度(例如200像素),并将背景颜色设置为&#34;清除颜色&#34;。清除颜色很重要,视图需要透明。
  4. 在表格标题UIView中删除第二个UIView,并使其大小与其父级相同。这将是实际的标题,因此请随意给它任何颜色,设置图像视图或其他内容。
  5. 将第二个UIView连接到你的UIViewController IBOutlet,我把它命名为#34; headerView&#34;就我而言。
  6. 接下来,转到您的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:方法更改为:
    4. <强> 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 
    }
}