How to Prevent Uinavigationbar from Covering Top of View in iOS 7

How to prevent UINavigationBar from covering top of view in iOS 7?

Set the navigation bar's translucent property to NO:

self.navigationController.navigationBar.translucent = NO;

This will fix the view from being framed underneath the navigation bar and status bar.

If you have to show and hide the navigation bar, then use

 if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone; // iOS 7 specific

in your viewDidLoad method.

View got hidden below UINavigationBar iOS 7

Try navigationBar.translucent = NO;, It is YES by default in iOS7.

It is also good to take a look on this part of UINavigationBar documentation:

New behavior on iOS 7. Default is YES. You may force an opaque
background by setting the property to NO. If the navigation bar has a
custom background image, the default is inferred from the alpha values
of the image—YES if it has any pixel with alpha < 1.0 If you send
setTranslucent:YES to a bar with an opaque custom background image it
will apply a system opacity less than 1.0 to the image. If you send
setTranslucent:NO to a bar with a translucent custom background image
it will provide an opaque background for the image using the bar's
barTintColor if defined, or black for UIBarStyleBlack or white for
UIBarStyleDefault if barTintColor is nil.

Edit:

Setting 'navigationBar.translucent' value causes exception if you run project in devices/simulators having older iOS versions.

So you can add a version check like this:

float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0)
{
navigationBar.translucent = NO;
}

Another option would be to set:

vc.edgesForExtendedLayout = UIRectEdgeNone;

Swift 3:

vc.edgesForExtendedLayout = []

iOS 7 Navigation Bar Hiding Content

I think there's still a little bit of misconception going around this layout problem even if iOS 7 was rolled out more than a year ago. So I eventually decided to elaborate further my answer.

Here's the thing.

Because automaticallyAdjustsScrollViewInsets' default value is YES, a pretty straightforward solution could be adding the following code:

if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) { // if iOS 7
self.edgesForExtendedLayout = UIRectEdgeNone; //layout adjustements
}

into the ViewController's -viewDidLoad method.

If you wish to remove the status bar quirk (due to the bar translucency, so it's not weird whatsoever) add self.navigationController.navigationBar.translucent = NO. The default value is YES.
Note: this has nothing to do with the content, it's related to the content because of translucency but that's an altogether different story!

Because extendedLayoutIncludesOpaqueBars is NO by default, self.navigationController.navigationBar.translucent = NO means basically having

self.edgesForExtendedLayout = UIRectEdgeLeft | UIRectEdgeRight| UIRectEdgeBottom; 

Or, more generally, something like that (it's like pseudocode to give an idea...)

BOOL enableTopEdge =  extendedLayoutIncludesOpaqueBars && !navigationBarIsTranslucent
self.edgesForExtendedLayout = (enableTopEdge & UIRectEdgeTop) | UIRectEdgeLeft | UIRectEdgeRight | UIRectEdgeBottom;

Status bar and navigation bar appear over my view's bounds in iOS 7

You can achieve this by implementing a new property called edgesForExtendedLayout in iOS7 SDK. Please add the following code to achieve this,

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;

You need to add the above in your -(void)viewDidLoad method.

iOS 7 brings several changes to how you layout and customize the
appearance of your UI. The changes in view-controller layout, tint
color, and font affect all the UIKit objects in your app. In
addition, enhancements to gesture recognizer APIs give you finer
grained control over gesture interactions.

Using View Controllers

In iOS 7, view controllers use full-screen layout. At the same time,
iOS 7 gives you more granular control over the way a view controller
lays out its views. In particular, the concept of full-screen layout
has been refined to let a view controller specify the layout of each
edge of its view.

The wantsFullScreenLayout view controller property is deprecated in
iOS 7. If you currently specify wantsFullScreenLayout = NO, the view
controller may display its content at an unexpected screen location
when it runs in iOS 7.

To adjust how a view controller lays out its views, UIViewController
provides the following properties:

  • edgesForExtendedLayout

The edgesForExtendedLayout property uses the UIRectEdge type,
which specifies each of a rectangle’s four edges, in addition to
specifying none and all. Use edgesForExtendedLayout to specify which
edges of a view should be extended, regardless of bar translucency. By
default, the value of this property is UIRectEdgeAll.

  • extendedLayoutIncludesOpaqueBars

If your design uses opaque bars, refine edgesForExtendedLayout by
also setting the extendedLayoutIncludesOpaqueBars property to
NO. (The default value of extendedLayoutIncludesOpaqueBars is NO.)

  • automaticallyAdjustsScrollViewInsets

If you don’t want a scroll view’s content insets to be automatically
adjusted, set automaticallyAdjustsScrollViewInsets to NO. (The
default value of automaticallyAdjustsScrollViewInsets is YES.)

  • topLayoutGuide, bottomLayoutGuide

The topLayoutGuide and bottomLayoutGuide properties indicate the
location of the top or bottom bar edges in a view controller’s view.
If bars should overlap the top or bottom of a view, you can use
Interface Builder to position the view relative to the bar by creating
constraints to the bottom of topLayoutGuide or to the top of
bottomLayoutGuide. (If no bars should overlap the view, the bottom of
topLayoutGuide is the same as the top of the view and the top of
bottomLayoutGuide is the same as the bottom of the view.) Both
properties are lazily created when requested.

Please refer, apple doc

How to prevent UINavigationBar from blocking touches on view

Subclass UINavigationBar and override- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event such that it returns NO for the rect where the view you want to receive touches is and YES otherwise.

For example:

UINavigationBar subclass .h:

@property (nonatomic, strong) NSMutableArray *viewsToIgnoreTouchesFor; 

UINavigationBar subclass .m:

- (NSMutableArray *)viewsToIgnoreTouchesFor
{
if (!_viewsToIgnoreTouchesFor) {
_viewsToIgnoreTouchesFor = [@[] mutableCopy];
}
return _viewsToIgnoreTouchesFor;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
BOOL pointInSide = [super pointInside:point withEvent:event];
for (UIView *view in self.viewsToIgnoreTouchesFor) {

CGPoint convertedPoint = [view convertPoint:point fromView:self];
if ([view pointInside:convertedPoint withEvent:event]) {
pointInSide = NO;
break;
}
}

return pointInSide;
}

In your fullscreen viewController where you have the view behind the navBar add these lines to viewDidLoad

UINavigationBarSubclass *navBar = 
(UINavigationBarSubclass*)self.navigationController.navigationBar;
[navBar.viewsToIgnoreTouchesFor addObject:self.buttonBehindBar];

Please note: This will not send touches to the navigationBar, meaning if you add a view which is behind buttons on the navBar the buttons on the navBar will not receive touches.

Swift:

var viewsToIgnore = [UIView]()

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {

let ignore = viewsToIgnore.first {
let converted = $0.convert(point, from: self)
return $0.point(inside: converted, with: event)
}
return ignore == nil && super.point(inside: point, with: event)
}

See the documentation for more info on pointInside:withEvent:

Also if pointInside:withEvent: does not work how you want, it might be worth trying the code above in hitTest:withEvent: instead.

iOS 7 Status Bar Collides With NavigationBar

The latest version of the iOS has brought many visual changes and from a developer's point of view, the navigation and status bar are two noticeable changes.

The status bar is now transparent and navigation bar behind it shows through. The navigation bar image can even be extended behind the status bar.

First of all, if you are a beginner and have just started iOS development and are confused the way status bar and navigation bar is working, you can simply go through a blog post HERE that i found very useful. It has all the information related to navigation and status bar in iOS 7.

Now coming to the answer of your question. First of all i can see two different problems. One is that your status bar and navigation bar are both kind of colliding with each other as shown by you in the question with an image.

PROBLEM: Well the problem is that your have earlier dragged a navigation bar in your view controller which was working in iOS 6 correctly but with the arrival of iOS 7 SDK, this approach is resulting in status bar and navigation bar overlapping with each other.

SOLUTION to First Problem: You can either use UIBarPositionTopAttached or you can use view bounds and frames, i can also suggest and link you to Apple's documentation and bla bla bla but that would take some time for you to solve the issue.

The best and the most easiest way to solve this issue is to just embed your view controller inside a navigation controller and thats it. You can do it by just selecting the view controller and going to Editor > Embed In > Navigation Controller. (If there is any content on your old navigation bar, you can first drag it down, embed the view controller in navigation controller and then move the bar buttons on the new navigation bar and then delete the old navigation bar)

SOLUTION to Second Problem: This solution is for your specific question that you have mentioned in the update and is not for the general public reading this. As you can see that navigation and status bar is not visible and a transparent area is showing the parent view controller. I am not really use why you are facing this issue but most probably because of some third party library like ECSlidingView or any other is involved. You can select this view controller in your storyboard and set the background color of the view to be the same as your navigation bar. This will stop showing the parent view controller behind and your navigation bar and status bar will start showing. Now you can cover the rest of your view controller with text view or what ever your are using in it.

Hope this helps!

ios7 - iPhone 5 giving white space at the top

try to insert following code into your viewDidLoad:

if( [self respondsToSelector:@selector(edgesForExtendedLayout)] ) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}

Otherwise you could try it, by removing the UIStatusBar. Select your Project, go to the section General and select Hide during application launch inside the subsection Deployment Info. Next you have to add the attribute inside the Info section called View controller-based status bar appearance and set it to NO.

How to make a UINavigationBar NOT push down views?

The navigation bar will always push down the view unless it's set to be translucent.



Related Topics



Leave a reply



Submit