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 高度?的主要内容,如果未能解决你的问题,请参考以下文章