iPhone - 如何设置 uinavigationbar 高度?

Posted

技术标签:

【中文标题】iPhone - 如何设置 uinavigationbar 高度?【英文标题】:iPhone - How set uinavigationbar height? 【发布时间】:2011-01-09 03:33:39 【问题描述】:

我想让导航视图的顶部变小一点。您将如何实现这一目标?这是我迄今为止尝试过的,但正如您所见,即使我将导航栏变小,它曾经占据的区域仍然存在(黑色)。

[window addSubview:[navigationController view]];
navigationController.view.frame = CGRectMake(0, 100, 320, 280);
navigationController.navigationBar.frame = CGRectMake(0, 0, 320, 20);
navigationController.view.backgroundColor = [UIColor blackColor];
[window makeKeyAndVisible];

【问题讨论】:

为什么要更改标准,我认为您应该设计视图以适应剩余空间。它违反了[人机界面指南][1]。 [1]:developer.apple.com/iphone/library/documentation/UserExperience/… 这更像是一件让我烦恼的事情。也许我想让导航栏更大。如果我现在这样做,它将覆盖内容(在本例中为 tableview)。 您应该选择一个答案 - 我建议使用 mackross,因为所有其他简单的答案都会导致子视图下移。 【参考方案1】:

使用自定义 sizeThatFits 创建一个 UINavigationBar 类别。

@implementation UINavigationBar (customNav)
  - (CGSize)sizeThatFits:(CGSize)size 
    CGSize newSize = CGSizeMake(self.frame.size.width,70);
    return newSize;
  
@end

【讨论】:

很棒的发现!也许最好使用 super 返回的内容然后更改 height 属性?编辑:刚刚意识到这在一个类别中不起作用,只在子类中起作用。 对于那些想要采用@aegzorz 建议的方法的人 - 如果使用本文中 Sebastian Celis 建议的方法,则使用子类没有问题:sebastiancelis.com/2012/03/05/subclassing-hard-to-reach-classes 使用子类而不是类别,在这里您更改基本实现以及使用它的任何代码都会丢失基本实现。太糟糕了!【参考方案2】:

使用这个导航栏子类,我已经成功地在 iPad 上的 ios 5.x 到 iOS 6.x 上创建了一个更大的导航栏。这给了我一个更大的导航栏,但不会破坏所有的动画。

static CGFloat const CustomNavigationBarHeight = 62;
static CGFloat const NavigationBarHeight = 44;
static CGFloat const CustomNavigationBarHeightDelta = CustomNavigationBarHeight - NavigationBarHeight;

@implementation HINavigationBar

- (id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if (self) 
//      UIColor *titleColor = [[HITheme currentTheme] fontColorForLabelForLocation:HIThemeLabelNavigationTitle];
//      UIFont *titleFont = [[HITheme currentTheme] fontForLabelForLocation:HIThemeLabelNavigationTitle];

//      [self setTitleTextAttributes:@ UITextAttributeFont : titleFont, UITextAttributeTextColor : titleColor ];

        CGAffineTransform translate = CGAffineTransformMakeTranslation(0, -CustomNavigationBarHeightDelta / 2.0);
        self.transform = translate;
        [self resetBackgroundImageFrame];

    
    return self;


- (void)resetBackgroundImageFrame

    for (UIView *view in self.subviews) 
        if ([NSStringFromClass([view class]) rangeOfString:@"BarBackground"].length != 0) 
            view.frame = CGRectMake(0, CustomNavigationBarHeightDelta / 2.0, self.bounds.size.width, self.bounds.size.height);
        
    


- (void)setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics

    [super setBackgroundImage:backgroundImage forBarMetrics:barMetrics];
    [self resetBackgroundImageFrame];


- (CGSize)sizeThatFits:(CGSize)size

    size.width = self.frame.size.width;
    size.height = CustomNavigationBarHeight;
    return size;


- (void)setFrame:(CGRect)frame

    [super setFrame:frame];
    [self resetBackgroundImageFrame];




@end

【讨论】:

不错的转换解决方案。谢谢!我有两种方法可以在 resetBackgroundImageFrame 代码中获取背景图像视图: 1,[self.subview objectAtIndex:0] - 我们可以非常安全地假设背景视图将位于堆栈的底部 - 它是一个背景,对吗? 2、使用KVO [self valueForKey:@"backgroundView"],这是我决定采用的方法。 如何应用这个子类? UINavigationController 的 initWithNavigationBarClass... 方法 如果您从 xib/storyboard 加载 UINavigationBar/UINavigationController,则需要改写 - (id)initWithCoder:(NSCoder *)aDecoder 这是一个不错的解决方案。我只是将它放入我的自定义类并运行我的应用程序;效果非常好(iOS 6,尚未在 iOS 5 上测试)。【参考方案3】:

为了快速

创建 Uinavigation bar 的子类。

import UIKit

class higherNavBar: UINavigationBar 

override func sizeThatFits(size: CGSize) -> CGSize 
    var newSize:CGSize = CGSizeMake(self.frame.size.width, 87)
    return newSize

两边会有两条空白条,我把宽度改成准确的数字才行。

但是标题和后退按钮与底部对齐。

【讨论】:

“但是标题和后退按钮是对齐到底部的”他们的解决方案是什么【参考方案4】:

没有必要对 UINavigationBar 进行子类化。在 Objective-C 中你可以使用类别,在 Swift 中你可以使用扩展。

extension UINavigationBar 
    public override func sizeThatFits(size: CGSize) -> CGSize 
        return CGSize(width: frame.width, height: 70)
    

【讨论】:

【参考方案5】:

我发现以下代码在 iPad(和 iPhone)上表现更好:

- (CGSize)sizeThatFits:(CGSize)size

     return CGSizeMake(self.superview.bounds.size.width, 62.0f);

【讨论】:

【参考方案6】:

如果您想为导航栏使用自定义高度,我认为您至少应该使用自定义导航栏(不是导航控制器中的导航栏)。隐藏 navController 的栏并添加您自己的。然后你可以将它的高度设置为你想要的任何值。

【讨论】:

设置高度不是问题,更多的是其他事情,在这种情况下,当导航栏改变其大小时,内容(tableview)似乎没有调整其位置。添加我的自定义导航栏将如何影响内容? NavController-with-navBar 的视图层次结构有点复杂。有一个父视图、一个导航栏,然后内容存储在视图控制器的视图中。如果您调整导航栏的大小,它不一定会调整控制器视图的大小。如果您调整内容的大小,您可以更好地控制重新流动以适合的内容。 我还发现调整导航栏的大小不能与 UITableViews、UITabBarControllers 等一起使用。苹果的硬编码似乎太多了。 (我尝试在 UINavigationControllerDelegate 中设置 tabBar 的高度)。 @Ben Gottlieb @benvolioT 所以,总而言之,现在有办法改变 navigationBar 的高度吗? 关于这个问题的任何更新?我有完全一样的问题。或者,导航栏的自定义设计必须是 44px ?【参考方案7】:

我能够在 Swift 中使用以下子类代码。它使用现有高度作为起点并添加到它。

与此页面上的其他解决方案不同,在横向和纵向之间切换时,它似乎仍然可以正确调整大小。

class TallBar: UINavigationBar 
    override func sizeThatFits(size: CGSize) -> CGSize 
        var size = super.sizeThatFits(size)
        size.height += 20
        return size
    

【讨论】:

唯一的问题是标题和栏按钮向下移动 - 所有新空间都在顶部。 这是真的,但就我而言,这实际上正是我想要做的。我在导航栏上方放置了一个小的分段控件,按钮本身显示在下方。但是很好 - 如果有人试图简单地在现有导航栏区域下方添加空间,这可能不是最佳解决方案。 我刚刚得到了在 iOS9 中工作的@macross 解决方案(不使用图像,但使用相同的覆盖)。我必须创建一个更高的导航栏,按钮和标题处于正常位置。我早上大部分时间都在做这件事(PITA)。无论如何,您所拥有的是解决方案的必要组成部分! 公平警告 - 此解决方案将不再适用于 iOS 11。【参考方案8】:

这是一个非常好的 Swift 子类,您可以在 Storyboard 中进行配置。它基于 mackross 所做的工作,这很棒,但它是 iOS7 之前的版本,会导致您的导航栏无法延伸到状态栏下方。

class UINaviationBarCustomHeight: UINavigationBar 

// Note: this must be set before the navigation controller is drawn (before sizeThatFits is called),
// so set in IB or viewDidLoad of the navigation controller
@IBInspectable var barHeight: CGFloat = -1
@IBInspectable var barHeightPad: CGFloat = -1

override func sizeThatFits(size: CGSize) -> CGSize 
    var customSize = super.sizeThatFits(size)
    let stockHeight = customSize.height
    if (UIDevice().userInterfaceIdiom == .Pad && barHeightPad > 0) 
        customSize.height = barHeightPad
    
    else if (barHeight > 0) 
        customSize.height = barHeight
    
    // re-center everything
    transform = CGAffineTransformMakeTranslation(0, (stockHeight - customSize.height) / 2)
    resetBackgroundImageFrame()
    return customSize


override func setBackgroundImage(backgroundImage: UIImage?, forBarPosition barPosition: UIBarPosition, barMetrics: UIBarMetrics) 
    super.setBackgroundImage(backgroundImage, forBarPosition: barPosition, barMetrics: barMetrics)
    resetBackgroundImageFrame()


private func resetBackgroundImageFrame() 
    if let bg = valueForKey("backgroundView") as? UIView 
        var frame = bg.frame
        frame.origin.y = -transform.ty
        if (barPosition == .TopAttached) 
            frame.origin.y -= UIApplication.sharedApplication().statusBarFrame.height
        
        bg.frame = frame
    


【讨论】:

【参考方案9】:

我还是 ios 的新手。我通过以下方式解决了问题:

    我创建了一个继承自 UINavigationBar 的新类

    我重写了以下方法:

     (void)setBounds:(CGRect)bounds 
    
       [super setBounds:bounds];
       self.frame = CGRectMake(0, 0, 320, 54);
    
    
      
    

3.为了获得导航栏的自定义背景,我重写了以下方法:

-(void)drawRect:(CGRect)rect 

    [super drawRect:rect];

    UIImage *img = [UIImage imageNamed:@"header.png"];

    [img drawInRect:CGRectMake(0,0, self.frame.size.width, self.frame.size.height)];



    在xib文件中,我已将导航栏的默认UINavigationBar类更改为我的类。

【讨论】:

这非常接近,但是它将与底层视图重叠,而不是移动它以与导航栏对齐。

以上是关于iPhone - 如何设置 uinavigationbar 高度?的主要内容,如果未能解决你的问题,请参考以下文章

苹果电脑如何设置iphone手机铃声

iPhone:如何独立于音量设置大声播放本地通知声音?

如何设置iphone输入法颜色

iphone - 如何将普通文本添加到设置包

iPhone - 如何设置 uinavigationbar 高度?

如何在 iphone 5s 和 iphone X 的情节提要中为 uibutton 设置不同的大小?