Center elements vertically inside UINavigationBar with custom height

落花浮王杯 提交于 2019-12-06 04:35:58

问题


I'm developing an iOS 6 and 7 app that requires the navigation bar to be taller than the usual 44/64 pts I've searched high and low and so far it seems the cleanest solution is to use a category (or subclass) and implement the - (CGSize)sizeThatFits:(CGSize)size method to return a different size.

This works fine in just making , however doing this causes all the items inside to rest at the bottom of the navigation bar, while I'd like to have them centered. I have tried using the Appearance Proxy protocol to define vertical offsets for the buttons, specifically this code

[[UIBarButtonItem appearance] setBackgroundVerticalPositionAdjustment: -10    forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundVerticalPositionAdjustment: -10 forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment: -10 forBarMetrics: UIBarMetricsDefault];

Works just fine on iOS 6, producing this result

But doesn't work on iOS 7, giving me this instead.

I have read around that under iOS 7 the adjustments only work when using custom views but it seems odd to me, especially considering that setBackButtonTitlePositionAdjustment:forBarMetrics: actually moves the text for the back button up, but not the chevron and that the title actually does nudge up.

I've also tried going for a subclassing route, using layoutSubviews to move down the views inside the UINavigationBar. This works, but of course when a new view controller is pushed the buttons jump around during the transition.

Am I missing something? Thanks in advance

UPDATE I have edited the description to make it clearer that my issue is with what's inside the bar, not the bar itself.


回答1:


The cleanest solution I've found to this problem was to use my own subclass of UINavigationBar and center the buttons vertically by overriding the layoutSubviews method:

- (void)layoutSubviews
{
    [super layoutSubviews];

    NSArray *subviews = self.subviews;
    for (UIView *view in subviews) {
        if ([view isKindOfClass:[UIButton class]]) {
            view.frame = ({
                CGRect frame = view.frame;
                CGFloat navigationBarHeight = CGRectGetHeight(self.frame);
                CGFloat buttonHeight = CGRectGetHeight(view.frame);
                frame.origin.y = (navigationBarHeight - buttonHeight) / 2.0f;
                frame;
            });
        }
    }
}

To make a UINavigationController use your subclass of UINavigationBar you can use the initWithNavigationBarClass:toolbarClass: initialiser:

UINavigationController *navigationController = [[UINavigationController alloc] initWithNavigationBarClass:[MyNavigationBar class] toolbarClass:nil];



回答2:


Did you try to add the following code to your viewDidLoad Method :

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

It is quickly explained in Apple migrating to iOS 7 Documentation : https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/AppearanceCustomization.html

//it's leave the status-bar height above.




回答3:


There is a quick crack to this, unless you find the proper solution, this would definitely work ;)

  • Check for system running iOS7.

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
       // Add below code
    }
    
  • Add Label to the Navigation Bar :

    UINavigationBar *bar = [self.navigationController navigationBar];
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(110, 55, 150, 20)]; //Set the frame appropriate to your screen
    label.backgroundColor = [UIColor clearColor];
    label.font = [UIFont boldSystemFontOfSize:14];
    label.adjustsFontSizeToFitWidth = NO;
    label.textAlignment = UITextAlignmentCenter;
    label.textColor = [UIColor blackColor];
    label.highlightedTextColor = [UIColor blackColor];
    [bar addSubview:label];
    



回答4:


Swift 3 version of Tiago his answer

override func layoutSubviews() {
    super.layoutSubviews()

    subviews.filter { (subview) -> Bool in
        return subview is UIButton
    }.forEach { (subview) in
        subview.center.y = frame.height / 2
    }
}

Adjusting the titleView vertical postion

setTitleVerticalPositionAdjustment(-10, for: .default)



回答5:


You can change size of navigation bar with just changing it's frame:

CGRect navigationBarFrame = self.navigationController.navigationBar.frame;



来源:https://stackoverflow.com/questions/20883052/center-elements-vertically-inside-uinavigationbar-with-custom-height

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!