以编程方式快速更改导航栏的高度

Posted

技术标签:

【中文标题】以编程方式快速更改导航栏的高度【英文标题】:Programmatically change height of navigation bar in swift 【发布时间】:2015-08-14 09:07:00 【问题描述】:

我想制作一个更高的导航栏,我正在尝试使用 UINavigationBar 的子类来做到这一点。

这是我的 UINavigationBar 的子类:

import UIKit
class TallerNaviBar: UINavigationBar 
    override func sizeThatFits(size: CGSize) -> CGSize 
        var newSize:CGSize = CGSizeMake(size.width, 87)
        return newSize
    

在我嵌入导航控制器的 ViewController 中,我在 viewDidLoad() 函数中编写了以下代码

self.navigationController!.setValue(TallerNaviBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 87)), forKeyPath: "navigationBar")

没有报告错误,但运行代码时我什么也没得到。一个完全空白的视图。 。

有什么建议吗?或者其他改变高度的方法?谢谢。

【问题讨论】:

答案在 swift, 不错的投票中,不客气 @Larcerax。谢谢您的回答。但我的声望点只有 8,这意味着我不能投反对票。很抱歉你投了反对票,但不是我。 所以,第一个答案是正确的答案,带有 : self.superview!.frame.size.width, 87) 的那个尝试一下,你会发现它应该可以正常工作, type cast the viewcontroller, 如果你知道如何在 Swift 中做到这一点,对不起预判 @Larcerax。我也不能投票,否则我会弥补你的损失。赞成票的最小值为 15,反对票的最小值为 125。***.com/help/privileges/vote-up。 ***.com/help/privileges/vote-down 你很高兴,别担心,我有其他类型的转换可能会为你工作, 【参考方案1】:

iOS 11 及更高版本的更新

苹果不想让你弄乱导航栏的高度,所以不要碰它 见这里:https://openradar.appspot.com/32912789 在这里:https://forums.developer.apple.com/thread/88202#274620

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

我不会快速,但答案很简单,这里是 ObjC

- (CGSize)sizeThatFits:(CGSize)size 

         return CGSizeMake([self superview].frame.size.width, 40);


这是我对 Swift 的解释:

import UIKit
class TallerNaviBar: UINavigationBar 
    override func sizeThatFits(size: CGSize) -> CGSize 
        var newSize:CGSize = CGSizeMake(superview.width, 87)
        return newSize
    

你会遇到的问题不是这个方法,这是简单的部分,问题是强制导航控制器总是使用这个导航栏

我对 ios 中的所有内容进行子类化和调整大小,包括导航控制器和 tabbarcontrollers,为了强制所有导航控制器使用此导航栏,您必须子类化一个 navigationController,并且仅在整个应用程序中使用此导航控制器,这是子类的工作方式,这是 Obj C,所以你必须翻译它:

@interface NSHNavigationController () <UINavigationBarDelegate, UINavigationControllerDelegate>




@implementation NSHNavigationController

#pragma mark Initialization

- (id)initWithCoder:(NSCoder *)aDecoder

    self = [super initWithCoder:aDecoder];
    if (self) 
        [self NSHSetupNavigationController];
    
    return self;


- (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass

    self = [super initWithNavigationBarClass:navigationBarClass toolbarClass:toolbarClass];
    if (self) 
        [self NSHSetupNavigationController];
    
    return self;


- (id)initWithRootViewController:(UIViewController *)rootViewController

    self = [super initWithRootViewController:rootViewController];
    if (self) 
        [self NSHSetupNavigationController];
    
    return self;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        [self NSHSetupNavigationController];
    
    return self;


- (void)dealloc

    [self setInternalDelegate:nil];
    [self setExternalDelegate:nil];


#pragma mark Setup

- (void)NSHSetupNavigationController

    [self setValue:[[NSHNavigationBar alloc]init] forKeyPath:@"navigationBar"];

这条线将为您完成:

   [self setValue:[[NSHNavigationBar alloc]init] forKeyPath:@"navigationBar"];

哦,是的,请确保您将导航栏子类化,您说过是的,但您是这样做的,很简单:

#import "NSHNavigationBar.h"

@implementation NSHNavigationBar
- (id)initWithFrame:(CGRect)frame 
    self = [super initWithFrame:frame];
    if (self) 
        NSDictionary *attributes = @NSForegroundColorAttributeName:[UIColor whiteColor],
                                     NSFontAttributeName:fontMagicForRegularNSHFont;
        [self setTitleTextAttributes:attributes];
        [self setTranslucent:true];
        [self setBackgroundColor:[UIColor clearColor]];
    
    return self;

- (CGSize)sizeThatFits:(CGSize)size 

    return CGSizeMake([self superview].frame.size.width, heightResizer(40));



- (void)layoutSubviews 

    [super layoutSubviews];


因此,总而言之,将 UINavigationBar 和 UINavigationController 子类化并设置好,这将允许您随时操作导航栏,您也可以键入转换视图控制器的导航栏,这有点疯了,会迷惑很多人,但这里是这样的:

-(CustomNavigationBar *)navBar 

    return (id)[self.navigationController navigationBar];

把上面的东西放在你的视图控制器中,然后你这样称呼它:

[[self navBar] setBackGroundColor:[UIColor blueColor]];

这将成功地将您的导航控制器类型转换为您的自定义导航栏,如果您想从这里更改导航栏的高度,那么您可以执行以下操作:

【讨论】:

不适用于 iOS 11。如上所述,我创建了 UINavigationController 和 UINavigationBar 的子类。在故事板中,将 UINavigationController 和 UINavigationBar 的类名更改为各自的子类名。但高度没有变化。 @Vakas 它不再受支持,请参见此处:forums.developer.apple.com/thread/88202#274620 和此处:openradar.appspot.com/32912789 苹果不希望您弄乱导航栏的高度,所以我不理会它,告诉您的客户到F关【参考方案2】:

这是一个基于最小子类化的简单 Swift 3 解决方案。第一个子类 UINavigationBar.:

class CustomNavigationBar: UINavigationBar 
    override func sizeThatFits(_ size: CGSize) -> CGSize 
        let newSize :CGSize = CGSize(width: self.frame.size.width, height: 54)
        return newSize
    

在代码中创建导航控制器并使用带有自定义导航栏类​​的初始化程序。

let nav = UINavigationController(navigationBarClass: CustomNavigationBar.self, 
                                 toolbarClass: nil)

UINavigationBar 的所有现有行为都将保留,并采用您的自定义高度。

【讨论】:

如何在 UIStoryboard 中设置自定义导航栏类​​?我尝试更改类名,但它不起作用。 ios11 不再支持 sizeThatFits 如何设置rootViewController?

以上是关于以编程方式快速更改导航栏的高度的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式获取 Android 导航栏的高度和宽度?

以编程方式更改标签栏和导航栏的颜色

如何以编程方式设置导航栏的标题?

以编程方式更改导航栏标题

XCode12 导航栏

常规高度导航栏的滚动边缘外观