【问题标题】:Instagram-like navigation bar (iOS 7)类似 Instagram 的导航栏 (iOS 7)
【发布时间】:2013-11-28 19:07:38
【问题描述】:

我正在尝试产生与 instagram 标题中相同的效果。我该怎么做?

我尝试了很多解决方案。

最佳 - https://github.com/andreamazz/AMScrollingNavbar

但它有一个大问题 - 它使用 uipangesturerecognizer 移动条。这对我很不利,因为如果桌子在顶部,我想显示栏。

我尝试将此控件的工作更改为滚动视图委托,但发现它有很多问题,您有什么想法,他们是如何做到的?

【问题讨论】:

    标签: ios uitableview uinavigationcontroller ios7 uinavigationbar


    【解决方案1】:

    我找到了解决方案,就像你说的那样 - 你必须稍微弄乱滚动视图委托,但大约 2 小时后我就搞定了。我试图解决的问题是能够像在 Instagram 中那样以一个连续的动作将标题取出。

    所以,首先检查 xib 设置,它在 (0 20, 320 85) 处有一个标题视图,它位于 (0 20, 320 548) 处的表视图后面

    这是启动后的样子(黄色的表格视图框架):

    这是我希望它在下拉后的样子(红色标题框):

    所以我只是用 cmets 粘贴代码,我希望它可以理解。

    定义

    #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 = 自我;这为我节省了几个小时,谢谢
    • 这应该被选为答案
    【解决方案2】:

    在 tableViewController 中使用 AMScrollingNavbar 并覆盖 willDisplayCell 方法以在表格滚动到顶部时显示栏:

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

    【讨论】:

      【解决方案3】:

      您可以在您的课程中使用下面提到的方法,在其中您想要在导航栏上添加效果,就像在 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;
      

      }

      【讨论】:

      • 这很好用,但导航栏只有在您滚动到顶部时才会重新出现。如果您决定在任何时候向上滚动,如何再次显示导航栏?
      【解决方案4】:

      使用该库,将其添加到您的视图控制器:

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

      【讨论】:

      • 或 scrollViewDidScrollToTop 然后你就不必返回任何东西了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多