以编程方式更改 swift 中导航栏的高度
Programmatically change height of navigation bar in swift
我想制作一个更高的导航栏,我正在尝试使用 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")
没有错误报告,但是当我 运行 代码时我什么也没得到。完全空白的视图。 。
有什么建议吗?或者其他改变高度的方法?谢谢
更新 iOS 11 岁及以后
apple 不想让你弄乱导航栏的高度,所以不要碰它
看这里: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
}
}
我不做 swift,但答案很简单,这里是 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 中的所有内容进行子类化和调整大小,包括导航控制器和 tabbarcontroller,为了强制所有导航控制器使用这个导航栏,你必须子类化一个 navigationController 并且只在你的应用程序中使用这个 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]];
这将成功地将您的导航控制器类型化为您的自定义导航栏,如果您想从这里更改导航栏的高度,那么您可以这样做:
这是一个简单的 Swift 3 基于最小子classing 的解决方案。第一个子class UINavigationBar.:
class CustomNavigationBar: UINavigationBar {
override func sizeThatFits(_ size: CGSize) -> CGSize {
let newSize :CGSize = CGSize(width: self.frame.size.width, height: 54)
return newSize
}
}
在代码中创建导航控制器并使用采用自定义导航栏的初始化程序class。
let nav = UINavigationController(navigationBarClass: CustomNavigationBar.self,
toolbarClass: nil)
保留 UINavigationBar 的所有现有行为并采用您的自定义高度。
我想制作一个更高的导航栏,我正在尝试使用 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")
没有错误报告,但是当我 运行 代码时我什么也没得到。完全空白的视图。
有什么建议吗?或者其他改变高度的方法?谢谢
更新 iOS 11 岁及以后
apple 不想让你弄乱导航栏的高度,所以不要碰它 看这里: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
}
}
我不做 swift,但答案很简单,这里是 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 中的所有内容进行子类化和调整大小,包括导航控制器和 tabbarcontroller,为了强制所有导航控制器使用这个导航栏,你必须子类化一个 navigationController 并且只在你的应用程序中使用这个 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]];
这将成功地将您的导航控制器类型化为您的自定义导航栏,如果您想从这里更改导航栏的高度,那么您可以这样做:
这是一个简单的 Swift 3 基于最小子classing 的解决方案。第一个子class UINavigationBar.:
class CustomNavigationBar: UINavigationBar {
override func sizeThatFits(_ size: CGSize) -> CGSize {
let newSize :CGSize = CGSize(width: self.frame.size.width, height: 54)
return newSize
}
}
在代码中创建导航控制器并使用采用自定义导航栏的初始化程序class。
let nav = UINavigationController(navigationBarClass: CustomNavigationBar.self,
toolbarClass: nil)
保留 UINavigationBar 的所有现有行为并采用您的自定义高度。