Use UICollectionView with transparent navigation bar - ios

I am building an iOS application and have done all the layouts using storyboards and auto layout.
I have a view controller with the view hierarchy as follows.
And for the collection view I have added constraints as follows,
For this whole view I have put a background image, as shown in the screen shot.
What I want to achieve is to make the navigation bar transparent and get the collection view to scroll only up to the point where the navigation bar is met.
I have tried setting the contentInset of the collection view as follows,
_collectionView.contentInset = UIEdgeInsetsMake(44, 0, 0, 0);
But there is no change.
I have also tried embedding the collection view inside another UIView, but still the collection view goes out of the bounds of that view as well.
With what I have right now the collection view scrolls as shown in the following screenshot.
Is there any way to resolve this? It'll be a great help if someone can help out.

You can't scroll up over the navigation bar. So, you need customize the bar like navigation bar.

You can use this:
[[UINavigationBar appearance] setBackgroundColor:[UIColor clearColor]];
[[UINavigationBar appearance] setTranslucent:YES];
It works for me.

You could try to set +44 in the y origin of your collection view:
self.collectionView.frame = CGRectMake(self.collectionView.frame.origin.x, 44, self.collectionView.frame.size.width, self.collectionView.frame.size.height);
and leave the contentInset with y=0:
collectionView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);

Related

CollectionView content goes under NavigationBar

I added a UICollectionViewController using IB. Then I added a UINavigationBar in code:
UINavigationBar *navBar = [[UINavigationBar alloc] init];
[navBar setFrame:CGRectMake(0, 20, self.view.frame.size.width, 44)];
[navBar setDelegate:self];
[self.view addSubview:navBar];
All works fine except the fact that the collection view content is hidden by the navigation bar. It doesn't only scroll beneath the navigation bar but in fact displays beneath it when first loaded.
How can I fix that?
Why are you using a standalone navigation bar? It's probably a bad idea. Embed your view controller in a UINavigationController, and make sure the top contraint of your UICollectionView is set to the top layout guide and not the view.
try changing your content offset of the collection view. I'd try either 44 (height of nav bar) or 64 (height of nav bar + status bar)
Your problem is adding UINavigationBar on self.view which is UICollectionView.
You may use simple UIViewController with UICollectionView as subview of its view. Then after adding UINavigationBar you have to change collectionView.frame.

UIScrollview position moves after touches begin

I view imbedded in a Navigation Controller which is slightly transparent. This view contains a UIscrollview. This UIScrollview has the following subviews: UIImageView, UILabel, and UIWebview. All these other views are working correctly. When the view loads, everything is in the correct position (The views are below the Navigation Bar). However, as soon as the screen is tapped, the scrollview repositions itself to the top of the view (aka behind the Navigation Bar, which is at the top, and I can see that this is true because the Nav Bar is slightly transparent)
Any idea why this is happening? I set up the scrollview like this:
self.scrollView.frame = CGRectMake(0, self.navigationController.navigationBar.frame.size.height, self.view.window.frame.size.width, self.view.window.frame.size.height);
Also set these properties:
self.scrollView.scrollEnabled = YES;
self.scrollView.alwaysBounceVertical = YES;
self.scrollView.bounces = YES;
Anybody know why this is happening?
I'd similar problem, but only on iOS 7.0. Try to set the translucent = NO property of the navigationBar. This will make the navigationBar opaque. Although if you want the navigationBar to be transparent, try to change the contentInset of the scrollView to adjust the content as you want. Hope that this will help :)

How do I position UITableView programmatically while using iOS7's UINavigationBar?

I have a quite regular UIViewController that is a part of a UINavigationController-hierarchy, which naturally makes the view have a UINavigationBar at the top. As we all know, iOS7's navigation bars are very different from previous versions.
If I drag a UITableView into my view in Storyboard, then the 'frame' for the table view is covering the entire view (I.E [tableView setFrame:self.view.frame];). Even behind the NavigationBar.
This makes so that if I scroll, the content will be faintly visible through the bar.
Contrary to most people, I actually like this.
In my current view controller, I would like to create the UITableView programmatically and place it as a subview here. However, I am unable to achieve the same effect this way.
I have tried
UITableView *table = [[UITableView alloc] initWithFrame:self.view.frame];
[self.view addSubview: table];
This makes the 'top scrolling point' stay behind the navigation bar. Imagine a single cell in a tableView, and it's faintly visible through the top bar. If I scroll down, it pops right up behind it. That's the default 'top position'.
I have also tried
CGRect frame = CGRectMake(0, 'nav.y+nav.height', self...width, self...height-y);
UITableView *table = [[UITableView alloc] initWithFrame:frame];
[self.view addSubview: table];
to simply place the table view in the rect below the UINavigationBar, but then I won't get the scrolling transparency effect behind the bar.
I also tried the first example along with this:
[tableView setContentOffset:CGPointMake(0, 'below navbar')];
which makes it stay exactly where I want it to stay, but as soon as I touch it (scroll and release), it scrolls back up behind the navigation bar, and stays there.
What's the programmatic solution to achieve this effect? Do I have to set the offset every time I scroll too far up, or is there a simpler solution? Along with this iOS7-style, I'd imagine they would add something like [tableView setVisibleFrame:] or something..?
Add the table in storyboard like normal but make sure you have it connected to an outlet (we will call it _tableView for now).
Then in your view controller's -viewDidLoad set the top inset to be the status bar plus the navigation bar:
`self.tableView.contentInset = UIEdgeInsetsMake( (self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height), 0, 0, 0);'
This will make sure that all of the cells will be visible but will also fill the area behind the navigation bar with white so the bar doesn't end up gray.

iOS 7 TableView in a ViewController and NavigationBar blurred effect

I started building a TableView in my app by using a TableViewController in a storyboard. When you do this, you have a very cool effect when you scroll down your list : the cells moving behind the nav bar get blurred.
Some time later, I had to move from this TableViewController to a ViewController with a TableView inside (I had to add other views at the bottom of the table).
In order to avoid having the first cells hidden by the navigation bar (being over it), I added constraints to the Top and Bottom Layout Guides, and to the left and right edges of the view.
This works fine, but I lost the cool blurred scrolling effect : the cells seem to be disappearing before going behind the navigation bar.
I've seen workarounds with people not using constraints and putting magic numbers in interface builder. I cannot do this, first because I dislike it, and second because I have to be iOS 6 compatible.
What did I miss to be able to benefit again from the blurred navigation bar effect ?
You have to manually adjust the contentInset of the table view and make sure the table view frame origin is 0, 0.
In this way the table view will be below the navigation bar, but there will be some margin between the content and the scroll view edges (the content gets shifted down).
I advise you to use the topLayoutGuide property of the view controller to set the right contentInsets, instead of hard coding 64 (status bar + navigation bar).
There's also bottomLayoutGuide, which you should use in case of UITapBars.
Here is some sample code (viewDidLoad should be fine):
// Set edge insets
CGFloat topLayoutGuide = self.topLayoutGuide.length;
tableView.contentInset = UIEdgeInsetsMake(topLayoutGuide, 0, 0, 0);
By the way, this properties of UIViewController might help you (you should not need to change their default values, but I don't know what your view hierarchy is):
automaticallyAdjustsScrollViewInsets
edgesForExtendedLayout
extendedLayoutIncludesOpaqueBars
The tableView needs to be full screen. That is underneath the top and bottom bars. Note don't use the top and bottom layout guides as they are used for positioning relative to the bars not underneath.
Then you need to manually set the content inset of the tableview. This sets the initial scroll position to under the top bar.
Something like:
CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
CGFloat h=MIN(statusBarSize.width, statusBarSize.height);
UIEdgeInsets e = UIEdgeInsetsMake(self.navigationController.navigationBar.bounds.size.height + h,
0.0f,
0.0f,
0.0f);
self.tableView.contentInset = e;
Not you get this functionality for free when using a tableView controller and the "Automatically Adjust content inset" settings
You probably have the coordinates of your tableView not set to (0, 0) to map to those of the viewController.view.frame or viewController.view.bounds. If you have done that, try setting
self.navigationController.navigationBar.translucent = YES;
UIViewController property edgesForExtendedLayout does the trick. If you are using storyboards just make sure Extended Edges Under Top Bars is on (and it is by default).
If you are creating your view controller programmatically try this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.edgesForExtendedLayout = UIRectEdgeAll;
}
And of course, your table view needs to have proper autoresizing mask/layout constraints
edgesForExtendedLayout is not what you want here, as this will limit the table view underneath the navigation bar. In iOS 7, the view controllers uses fullscreen by default, and the property controlling where the tableview content starts is automaticallyAdjustsScrollViewInsets. This should be YES by default, so check if it is somehow set to NO, or try setting it explicitly.
Check this answer for a good explanation on how this works:
https://stackoverflow.com/a/19585104/1485715

How come a UIViewController's view coordinate system starts after the navbar, but its height includes the navbar?

I noticed that with a NavigationController on an iPhone, the height is 460. So it includes the whole screen except the status bar.
However, when I add something at coordinate 0, it shows up after the NavigationBar, although the size of the navigation bar is included in the height (meaning the entire frame of this view sticks off the screen).
Did I make a mistake? If not, why is it structured this way?
NSLog(#"Frame: %#", [NSValue valueWithCGRect: self.view.frame]); // prints {(0, 20), (320, 460)}
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame: CGRectMake(0, self.navigationController.navigationBar.frame.size.height, self.view.frame.width, 50)];
[self.view addSubview: scrollView]; // showing up 44px *after* the nav bar
I already answered your other similar question, but here is one for this.
In viewDidLoad you will see the views height as 460 because at that point it hasn't resized to account for the Nav Bar.
But If you printed the same frame out in say viewWillAppear you will see that now the frames height has adjusted for the Nav Bar.
So if you want to add something in viewDidLoad, you need to add it based on the views frame, add whichever resizing mask will do the job you want, and see it adjust correctly once the view appears.

Resources