类似Instagram的导航栏(iOS 7)

3
我正在尝试制作与Instagram标题栏相同的效果。我该怎么做?
我尝试了很多解决方案。
最好的方法是https://github.com/andreamazz/AMScrollingNavbar,但它有一个大问题——使用uipangesturerecognizer移动栏。这对我来说很糟糕,因为我想在表格在顶部时显示栏。
我试图将此控件的工作更改为滚动视图委托,但发现了很多问题。你有任何想法他们是如何做到的吗?

instagram main screen

4个回答

3
我找到了解决方案,就像你说的那样 - 你需要稍微调整一下滚动视图委托,但经过大约两个小时的努力,我已经把它全部搞定了。我试图解决的问题是能够像在Instagram中一样以一个连续的动作将头部拉出来。
首先,请查看xib设置,它在(0 20, 320 85)处有一个标题视图,位于(0 20, 320 548)后面的表视图之后。
这是启动后的样子 (黄色为表格视图框架): after launch 这是我想要在拉下后的样子 (红色为标题框架): after pulling down 因此,我将附上带有注释的代码,希望足够易懂。
定义一个宏:
#define SIGNIFICANT_SCROLLING_DISTANCE 200

创建两个属性
@property (nonatomic) CGFloat lastScrollViewOffsetY;
@property (nonatomic) CGFloat distancePulledDownwards;

然后为 scrollViewDidScroll 委托方法添加以下实现:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    // store current scroll view frame as we will change it later on and set it
    // back to the scroll view in the very end
    CGRect currentScrollViewRect = scrollView.frame;
    // same with the content offset
    CGPoint currentScrollViewOffset = scrollView.contentOffset;
    CGFloat offsetShiftY = self.lastScrollViewOffsetY - scrollView.contentOffset.y;

    if (offsetShiftY > 0) {
        // pulling downwards
        // keep trrack of the distance that we pulled downwards
        self.distancePulledDownwards += offsetShiftY;

        // header opens (table view shifts its frame down) in two cases:
        // 1. contentOffset.y<0
        // 2. scrolled downwards a significant amount or header is already open
        // but in both cases we have to make sure that it doesn't open further than we want it to
        CGFloat wantedOriginY = currentScrollViewRect.origin.y;
        if ((scrollView.contentOffset.y<0) || (self.distancePulledDownwards > SIGNIFICANT_SCROLLING_DISTANCE) || (currentScrollViewRect.origin.y>20)){

            // shift scroll views frame by offset shift
            wantedOriginY = currentScrollViewRect.origin.y + offsetShiftY;
            // compensate that shift by moving content offset back
            currentScrollViewOffset.y += (wantedOriginY <= 105) ? offsetShiftY : 0;
        }
        currentScrollViewRect.origin.y = (wantedOriginY <= 105) ? wantedOriginY : 105;

    }
    else {
        // pulling upwards
        self.distancePulledDownwards = 0;

        // header closes (table view shifts its frame up) in one case: when it is open =) (and contentOffset.y>0 to eliminate closing on bounce)
        if (scrollView.contentOffset.y > 0) {
            CGFloat wantedOriginY = currentScrollViewRect.origin.y + offsetShiftY;
            currentScrollViewRect.origin.y = (wantedOriginY >= 20) ? wantedOriginY : 20;
            currentScrollViewOffset.y += (wantedOriginY >= 20) ? offsetShiftY : 0;
        }
    }

    // set the changed (if it was changed at all) frame to the scroll view
    [scrollView setFrame:currentScrollViewRect];

    // correct offset using a special trick
    // it ensures that scrollViewDidScroll: won't be called on setting the offset
    scrollView.delegate = nil;
    [scrollView setContentOffset:currentScrollViewOffset];
    scrollView.delegate = self;

    // and finally remember the current offset as the last
    self.lastScrollViewOffsetY = scrollView.contentOffset.y;
}

享受您在屏幕上流畅地滚动表格的过程=)这也可以进行修改,您可以添加和调整标题大小,使其基本与Instagram相同。


scrollView.delegate = nil; [scrollView setContentOffset:currentScrollViewOffset]; scrollView.delegate = self; 这个操作省了我好几个小时,谢谢。 - aryaxt
1
这应该被选为最佳答案。 - aryaxt

2

如果您想在某个类中添加与Instagram中导航栏相似的效果,可以使用下面提到的方法。

- (void)scrollViewDidScroll:(UIScrollView *)sender {
//Initializing the views and the new frame sizes.
UINavigationBar *navbar =self.navigationController.navigationBar;
UIView *tableView = self.view;
CGRect navBarFrame = self.navigationController.navigationBar.frame;

CGRect tableFrame = self.view.frame;

//changing the origin.y based on the current scroll view.
//Adding +20 for the Status Bar since the offset is tied into that.

if (isiOS7) {
     navBarFrame.origin.y = MIN(0, MAX(-44, (sender.contentOffset.y * -1)))  +20 ;
     tableFrame.origin.y = navBarFrame.origin.y + navBarFrame.size.height;
}else{
    navBarFrame.origin.y = MIN(0, (sender.contentOffset.y * -1)) +20;
    tableFrame.origin.y = MIN(0,MAX(-44,(sender.contentOffset.y * -1))) ;
}

navbar.frame = navBarFrame;
tableView.frame = tableFrame;

}


这个程序运行良好,但是导航栏只有当你滚动到顶部时才会重新出现。如果你在任何时候决定向上滚动,如何再次显示导航栏? - Halpo

2

使用AMScrollingNavbar与您的tableViewController,并重写willDisplayCell方法,以在表格滚动到顶部时显示栏:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) {
        [self showNavbar];
    }
}

1

使用该库,将以下内容添加到您的视图控制器中:

- (BOOL)scrollViewShouldScrollToTop {
    [self showNavbar];
    return YES;
}

或者scrollViewDidScrollToTop,然后你就不需要返回任何东西。 - Craig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接