iOS 11 UINavigation Bar is messed up - ios

With iOS 11 navigation bar's title view and bar button item is not centered.
Also the background image's height does not change and is not shown in full.The bar height is 74.
See the white space.
I have tried this
if(#available(iOS 11,*)){
_homeNavigationBar.prefersLargeTitles = NO;
_homeNavigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
[_homeNavigationBar setBarTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"navbarBg.png"]]];
}
else{
[_homeNavigationBar setBackgroundImage:[UIImage imageNamed:#"navbarBg.png"] forBarMetrics:UIBarMetricsDefault];
}
But still i am unable to center the title and bar button item.
Any idea how can i fix this?Please do let me know.Thanks

Subclassing the navigation bar did the trick for me.
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *view in self.subviews) {
if([NSStringFromClass([view class]) containsString:#"Background"]) {
view.frame = self.bounds;
}
else if ([NSStringFromClass([view class]) containsString:#"ContentView"]) {
CGRect frame = view.frame;
frame.origin.y = 25;
view.frame = frame;
}
}
}

Related

NavigationBar Layout has an exception when user has in call status bar

After I toggle in-call status bar, the navigation bar drops. And the content behind falls a height of 20 .
I can not figure out why.
The picture shows the scene.
Looks like the navigation bar drops. And the blue bar falls.
Seen from the view hierarchy debugger, I do not know why the blue bar has a distance from the navigation bar.
Here is the relevant code.
- (void)viewWillLayoutSubviews{
self.blueBar.translatesAutoresizingMaskIntoConstraints = NO;
[super viewWillLayoutSubviews];
[self.blueBar.topAnchor constraintEqualToAnchor: self.view.topAnchor].active = YES;
[self.blueBar.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor].active = YES;
[self.blueBar.trailingAnchor constraintEqualToAnchor: self.view.trailingAnchor].active = YES;
[self.blueBar.heightAnchor constraintEqualToConstant: 75].active = YES;
......
}
-(UIView *)blueBar{
if(!_blueBar){
_blueBar = [[UIView alloc] init];
_blueBar.backgroundColor = [UIColor blueColor];
}
return _blueBar;
}
The status bar height change from 20 to 40 when in-call.And I found you use tableView,so try this:
if (#available(iOS 11.0, *)) {
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
What's more,why not use mainstream frameworkMasonry?

iOS [Obj-C] - NavigationBar transparent with visible items while scrolling

This is my question
CONTEXT
I have a ViewController which I have an effect where the Navigation Bar gets transparent when the user go down in the scroll, and the Navigation Bar gets normal when the user go up in scroll view. This effect I did with the UIScrollViewDelegate's methods. This is the code:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat offset = scrollView.contentOffset.y;
if (scrollView.contentOffset.y < 0){
scrollView.bounces = false;
}else{
scrollView.bounces = true;
}
CGFloat currentAlpha = (offset / 310);
if (currentAlpha < 0) {
self.navigationController.navigationBar.translucent = YES;
self.navigationController.navigationBar.alpha = 1;
self.navigationController.titleNavBar.alpha = 0; //This property I made in an UINavigationController extension
} else {
self.navigationController.navigationBar.translucent = YES;
self.navigationController.navigationBar.alpha = 1;
self.navigationController.titleNavBar.alpha = currentAlpha; //This property I made in an UINavigationController extension
[self.navigationController.navigationBar setBackgroundColor:[UIColor colorWithRed:0.0f/0.0f green:136.0f/255.0 blue:206.00f/255.0f alpha:currentAlpha]];
}
}
With the previous code I got the effect, but I have a problem: I can't add it to the status bar because self.navigationController.navigationBar.translucent is set on YES. So, in the iPhones, the status bar shows transparent and in the iPhone X shows bigger this transparence than another iPhones (see the image).
Anyone know how can I do this transparent effect with Navigation Bar and the Statsus Bar?
You need to change statusBar UIView color with NavigationBar color.
Create AppDelegate SharedInastance :
+ (AppDelegate *)sharedAppDelegate {
return (AppDelegate *)[UIApplication sharedApplication].delegate;
}
Add below code in AppDelegate to get status bar view:
- (UIView *)statusBarView {
return [[[UIApplication sharedApplication] valueForKey:#"statusBarWindow"] valueForKey:#"statusBar"];
}
Add below code when you want to change status bar color:
[[AppDelegate sharedAppDelegate] statusBarView].backgroundColor = [UIColor redColor];

Change vertical position of back button text in UINavigationBar

I've been able to change the vertical posiiton of the back button icon but not the text.
I'm using the layoutSubviews method in UINavigationBar:
- (void)layoutSubviews {
[super layoutSubviews];
BOOL fixed = NO;
NSArray *classNamesToReposition = #[#"_UINavigationBarBackIndicatorView", #"UINavigationButton", #"UINavigationItemButtonView"];
for (UIView *view in [self subviews]) {
if ([classNamesToReposition containsObject:NSStringFromClass([view class])] && !fixed) {
CGRect frame = [view frame];
if ([NSStringFromClass([view class]) isEqualToString:#"_UINavigationBarBackIndicatorView"]) {
frame.origin.y = 14.5;
} else if ([NSStringFromClass([view class]) isEqualToString:#"UINavigationButton"]) {
frame.origin.y = 9.0;
} else if ([NSStringFromClass([view class]) isEqualToString:#"UINavigationItemButtonView"]) {
frame.origin.y = 5.0;
}
[view setFrame:frame];
}
}
}
The problem is that any frame change I make on UINavigationItemButtonView does not seem to have any effect, nor any frame change I make on it's UILabel subview that is the actual button text. When I log the views the frames seem to be changing but the text is not moving in my view. What am I doing wrong?
You subclass a UINavigationBar called MyNavigationBar, in layoutSubviews, change the back indicator position.
for (UIView *view in [self subviews]) {
CGRect frame = [view frame];
if ([NSStringFromClass([view class]) isEqualToString:#"_UINavigationBarBackIndicatorView"]) {
frame.origin.y = 19.5; //default is 11.5, move down by 8.
}
[view setFrame:frame];
}
And you can change backBarItem's title position by adding this in applicationDidFinished.
[[UIBarButtonItem appearanceWhenContainedIn:[MyNavigationBar class], nil] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, 8) forBarMetrics:UIBarMetricsDefault];

UItableview Separator line's height

Can I adjust the height of the UITableview's separator line? I add UIView at the cell to use as separator line and its good, the problem is that when I slide the cell to delete it, the delete button is the problem, its overlapping the separator line, or can I adjust the delete button's height?
The code pasted in by Rashad is pretty old (found here) and doesn't seem to work for iOS 7 or iOS 8.
Here is updated code that works:
-(void)layoutSubviews {
UIView *deleteButtonView = nil;
for (UIView *subview in self.subviews) {
// find the delete view in iOS 8
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationView"]){
deleteButtonView = subview;
break;
}
// find the delete view in iOS 7
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellScrollView"]) {
for (UIView *secondSubview in [subview subviews]) {
if ([NSStringFromClass([secondSubview class]) isEqualToString:#"UITableViewCellDeleteConfirmationView"]) {
deleteButtonView = secondSubview;
break;
}
}
}
}
int heightOffset = 5;
CGRect buttonFrame = deleteButtonView.frame;
buttonFrame.origin.y = heightOffset;
buttonFrame.size.height = self.frame.size.height-2*heightOffset;
deleteButtonView.frame = buttonFrame;
}
If you can't resize the delete button, resize your bottom UIView so it can overlap the delete button.
I always draw separator line like a subView on contentView of cell. And disable separatorStyle in tableView. And customise delete button like here: https://stackoverflow.com/a/22396248/887325
In you TableViewCell layoutSubviews method write this:
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
CGRect newf = deleteButtonView.frame;
newf.origin.x = 250;
newf.origin.y = 47;
newf.size.width = 30;
newf.size.height = 50;
deleteButtonView.frame = newf;
}
Hope this helps.. :)

Navigation controller with 2 navigation bars - how to adjust frame of pushed view controllers?

I have a UINavigationController to which I need to add a second UINavigationBar. Neither of those bars is translucent. Problem is, view controllers that I put inside this navigation controller are partially covered by my second navigation bar. Where do I adjust the frames of those view controllers' views so that I don't get a "blinking" effect of them changing frames while being visible?
EDIT:
This is in viewDidLoad:
UINavigationBar *secondaryNavBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, 50)];
secondaryNavBar.translucent = NO;
if ([secondaryNavBar respondsToSelector:#selector(setBarTintColor:)]) { //it has to work on iOS 6 as well
secondaryNavBar.barTintColor = [UIColor darkGrayColor];
secondaryNavBar.tintColor = [UIColor whiteColor];
}
else {
secondaryNavBar.tintColor = [UIColor darkGrayColor];
}
[self.view addSubview:secondaryNavBar];
self.secondaryNavBar = secondaryNavBar;
Here's a working solution. Certainly not the best, and I did not make it to support iOS 6, you'll have to work on it and test it.
CustomNavigationController.m :
#implementation CustomNavigationController {
UINavigationBar *bottomNavBar;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self showNavBar];
}
- (void)showNavBar {
UINavigationBar *secondaryNavBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, 50)];
secondaryNavBar.translucent = NO;
if ([secondaryNavBar respondsToSelector:#selector(setBarTintColor:)]) { //it has to work on iOS 6 as well
secondaryNavBar.barTintColor = [UIColor darkGrayColor];
secondaryNavBar.tintColor = [UIColor whiteColor];
}
else {
secondaryNavBar.tintColor = [UIColor darkGrayColor];
}
[self.view addSubview:secondaryNavBar];
bottomNavBar = secondaryNavBar;
[self layoutNavBar];
}
- (void)layoutNavBar {
// Get the currently displayed view
UIView *contentView = self.topViewController.view;
// Get its frame and height
CGRect contentFrame = contentView.frame;
float height = contentFrame.size.height;
// Adapt height and y origin with the new nav bar
contentFrame.size.height = height - bottomNavBar.frame.size.height;
contentFrame.origin.y = bottomNavBar.frame.origin.y + bottomNavBar.frame.size.height;
// Set the view's frame
contentView.frame = contentFrame;
}
#end
ViewController.m :
#implementation ViewController
-(void)viewDidAppear:(BOOL)animated {
CustomNavigationController *navigation = (CustomNavigationController*)self.navigationController;
[navigation layoutNavBar];
}
#end
Note that you have to call layoutNavBar on viewDidAppear, or the view's frame will be reset by your app. This is not a perfectly clean solution, but a pretty good fix.

Resources