目标C:如何使用tableview制作导航栏滚动

时间:2011-07-27 02:43:49

标签: objective-c ios uinavigationbar

我的应用程序的单个屏幕中有一个UITableView和一个导航栏。我想导航栏与表格的其余部分一起滚动。

注意:我目前正在实现一个UITableView,它被添加为uiviewcontroller的子视图,而uiviewcontroller又是导航控制器的一部分

有人可以告诉我如何做到这一点吗?

2 个答案:

答案 0 :(得分:6)

在下面的回答中,我隐藏了真正的导航栏并将其替换为假条。如果您想使用真实的导航栏,代码仍然有效,只需恢复viewWillDisappear中栏的原始位置。

隐藏导航控制器栏:

self.navigationController.navigationBar.hidden = YES;

添加顶栏作为当前控制器视图的子视图。

UIView *headerView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bar.png"]];
[self.view addSubView:headerView];

此时你有一个headerView和一个tableView。保存原始帧:

@property (nonatomic,assign) CGRect initialTableRect;
@property (nonatomic,assign) CGRect initialHeaderRect;

// This is how many pixels you are going to scroll up under the clock bar.
// To scroll your whole headerView, set it to self.headerView.frame.height
@property (nonatomic,assign) NSInteger kHiddenPixels;    

// viewDidLoad
self.initialTableRect = self.tableView.frame;
self.initialHeaderRect = self.headerView.frame;
self.kHiddenPixels = self.headerView.frame.height;

在视图控制器中添加它,它也是您的表委托:

#pragma mark UIScrollViewDelegateMethods

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    // 0 at the initial position, negative down, positive up
    CGPoint offset = aScrollView.contentOffset;

    if (offset.y>=0 && offset.y<=kHiddenPixels)
    {
        // move header
        CGRect newRect = self.initialHeaderRect;
        newRect.origin.y -= offset.y;
        self.headerView.frame = newRect;

        // move and resize table
        newRect = self.initialTableRect;
        newRect.origin.y -= offset.y;
        newRect.size.height += offset.y;
        self.tableView.frame = newRect;
    }
    else if (self.headerView.frame.origin.y!=0 || self.headerView.frame.origin.y!=kHiddenPixels)
    {
        // outside the scrolling area but frame is not on 0 or kHiddenPixels,
        // which means we skipped scroll because drag was to fast

        if (offset.y<0){
            // set initial position on header and table
            self.headerView.frame = self.initialHeaderRect;
            self.tableView.frame = self.initialTableRect;
        }
        else if (offset.y>kHiddenPixels)
        {
            // set scrolled up position on header
            CGRect rect = self.initialHeaderRect;
            rect.origin.y = -1*kHiddenPixels;
            self.headerView.frame = rect;

            // set scrolled up position on table            
            rect = self.initialTableRect;
            rect.size.height += kHiddenPixels;
            rect.origin.y -= kHiddenPixels;
            self.tableView.frame = rect;
        }
    }
}

这将检查表格高度并在表格视图滚动时移动顶部栏。由于tableView正在移动到之前由顶部栏填充的,所以我也在扩大表格视图的大小。

编辑:刚刚上传了implementation in github,顶栏为80像素,kHiddenPixels = 35:

enter image description here

可能的增强功能:现在,当tableView的第一行在顶部栏下滚动时,顶部栏会在时钟栏下方滚动。如果tableView和顶栏一起滚动直到顶栏消失,那么看起来会更自然,然后让第一行开始在顶栏下滚动。不知道如何做到这一点,可能使用平移手势识别器并禁用表滚动,直到隐藏栏。

答案 1 :(得分:1)

导航栏可以与表视图的其他单元格一起滚动的唯一方法是导航栏是表格视图的一部分还是更大的滚动视图的子视图(除了表格视图的子视图)。看看这个问题:How can I make the navigation bar scroll along with my webpage?。创建一个更大的滚动视图,并将表视图和导航栏添加到此滚动视图。如果你想让导航栏成为表格视图的一部分,你需要为它制作一个自定义单元格,这会带来更多的麻烦!