9

I need to implement something like this:

NavBar stay on top, tableView bounces

tableView must bounce, but not navigation bar.

I tried a bunch of different variants. Something like this:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGRect imageViewFrame = self.imageView.frame;
    CGRect tableViewFrame = self.tableView.frame;
    //ImageView - is top view(instead of NavBar)
    //defaultHeight - is default height of tableView
    imageViewFrame.origin.y = MIN(0, MAX(-scrollView.contentOffset.y, -100));
    tableViewFrame.origin.y = imageViewFrame.origin.y + 100;
    tableViewFrame.size.height = defaultHeight - imageViewFrame.origin.y;

    self.imageView.frame = imageViewFrame;
    self.tableView.frame = tableViewFrame;
}

Get this:

1 2

it is not suitable because in Instagram size of tableView doesn't change(just look at scroll indicators, if size of tableView changed, they also changed)

please look at scroll indicators please look at scroll indicators

Also I tried add View as subView into tableView, it works, but not exactly what I need is. In Instagram navigation bar outside the tableView, so it is not suitable too.

In the facebook app search bar behaves exactly the same

enter image description here

Can anyone help me?

Thanks!

wiruzx
  • 491
  • 3
  • 17
  • I am really not sure if I got this correct, are you saying you want a header view that overlays your content? Maybe put more annotations in your images because I do not see any navigation bars which may be what's confusing me. – 7usam Mar 12 '13 at 21:22
  • @7usam, I'm probably wrong to put it, I need to get the behavior of the navigation bar (or any other View) is the same as in Instagram or Facebook. – wiruzx Mar 12 '13 at 21:28
  • Are you talking about the "name tag" in Instagram? – 7usam Mar 12 '13 at 21:30
  • no, i'm talking about the navigation bar. But actually I do not care it will be navigation bar or just view, the main thing that it behaved the same way as in instagram – wiruzx Mar 12 '13 at 21:34
  • What about using your same approach in the sample code but rather than increasing the tableview's height, you can just pan it upwards. Have the tableview start out with the complete height (which is hidden by the tabbar until the nav view is out of the way) – 7usam Mar 12 '13 at 22:12
  • This should help! http://stackoverflow.com/a/13249526/1257657 – Moxy Mar 12 '13 at 22:18
  • @7usam i tried this, but it works incorrect =( – wiruzx Mar 12 '13 at 22:24

4 Answers4

1

The instagram "navigation bar" isn't a navigation bar. It's a table section header. You'll notice that when you tap on a photo, the entire navigation bar slides away. That's because it's part of the table view controller and not a "real" navigation bar.

You can achieve this by using a UINavigationController but hiding the navigation bar (setNavigationBarHidden:YES). You just call pushViewController:animated: manually when you want to push.

Interestingly it looks like the other tabs of instagram just use a normal navigation bar and don't do anything fancy. I guess they really wanted those 44 points back on the main feed screen.

jsd
  • 7,673
  • 5
  • 27
  • 47
  • but if this section header, then why it does not bounce with the rest of the table? and why the scroll indicator stops right in front of him? (screenshot # 5) – wiruzx Mar 12 '13 at 21:42
  • 1
    Wouldn't be a table header rather than a table section header? – 7usam Mar 12 '13 at 21:44
  • 1
    @7usam anyway in Instagram navbar outside the tableView – wiruzx Mar 12 '13 at 21:59
  • 1
    Well, you're right, it doesn't bounce. So I guess it isn't part of the table view. In that case, you'll have to implement it as a separate view, use your own scrollview instead of tableview, and track the scrollview's delegate messages to know when to scroll the header. – jsd Mar 12 '13 at 22:47
1

Have the same approach in the sample code but rather than increasing the tableview's height, you have it preloaded with the additional (not-visible height) and just move it upwards by decreasing the frame's y. The additional height will be off-screen. If the content height is not big enough to go off-screen then you don't need to have the off-screen height.

Add a header with height = 0 at start, and as you scroll down it increases the size, up to 100 (the empty header will be off screen now). That way the content will not get cut off as you scroll.

7usam
  • 999
  • 1
  • 8
  • 23
  • if you look at 2 and 3 screenshot, you must noticed that table view cells hides upon upper view. Speed of moving top view and cells is defferent because I changed y-cordinate of tableview – wiruzx Mar 13 '13 at 04:43
  • @wiruzx I see, the problem is that tableview scrolls. What do you think about adding a header, see edited answer. – 7usam Mar 13 '13 at 04:56
  • header for tableView? I tried it, it came out that headerView was inside tableView – wiruzx Mar 13 '13 at 09:02
  • @wiruzx yes header for table view. I don't think you understood my suggestion. So you follow the same approach in the sample code in your question, but without changing the table view size. Now because it will scroll the tableview will appear to get cut off (as you pointed out in screenshot 2 & 3), so to avoid that you also add a table header, and you change the size of the header to compensate for the "navigation bar" that is going off screen. That way your scroll position should appear to be scrolling but the text shouldn't cut off because you are scrolling the header away first. – 7usam Mar 13 '13 at 22:05
  • thanx, i get it, but the problem is that if the upper view is a header then scroll indicator will be on it, and I need that he would have stayed in front of him – wiruzx Mar 14 '13 at 08:09
  • 1
    @wiruzx at scroll offset = 0, header height = 0, so indicator will be at the start of cell[0]. at offset = 10, header height = 10, so indicator should be at point 10 (as the offset specifies) and at the start of cell[0] still. Am I wrong? – 7usam Mar 14 '13 at 21:24
  • Thank you very much! I just did not know about scrollIndicatorInsets. Now it works the way I wanted. =) – wiruzx Mar 15 '13 at 06:41
1

If you are targeting iOS 5+ than you can easily customize the navigation bar like this:

1- Add Your TableViewController inside a UINavigationController

2- Customize The Navigation Bar:

Set Background Image For Navigation Bar

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"bar_background"] 
                                   forBarMetrics:UIBarMetricsDefault];

Add Refresh Button on Right Side

UIImage *img = [UIImage imageNamed:@"refresh.png"];
UIButton *rButton = [UIButton buttonWithType:UIButtonTypeCustom];
[rButton setImage:img forState:UIControlStateNormal];
[rButton addTarget:vc action:@selector(didTapRefreshButton:) forControlEvents:UIControlEventTouchUpInside];
rButton.frame = CGRectMake(0.0f, 0.0f, img.size.width, img.size.height);
UIBarButtonItem *rButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rButton];

self.navigationItem.rightBarButtonItem = rButtonItem;
[rButtonItem release];

Hope that Helps!

Asif Mujteba
  • 4,596
  • 2
  • 22
  • 38
0

You can use the below mentioned method in your class in which you want to add effect on navigation bar as there in 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;

}