在 Cocoa Touch 中更改其内部的 NavigationBar 和 UIBarButtonItem 元素的高度

发布于 2024-12-18 08:56:50 字数 277 浏览 2 评论 0原文

我想这并不严格符合苹果的指导方针,但我想这一定是可能的。我想更改 UINavigationController 内导航栏的高度和该栏中 UIBarButtonItem 元素的高度。

使用这个问题中的技巧我设法改变了导航栏的高度,但我可以没有办法调整栏按钮项目的高度。

如果有人知道如何更改栏按钮项目的大小,请帮助我。

I suppose it's not strictly in line with Apple guidelines but I guess it must be possible somehow. I'd like to change the height of navigation bar inside UINavigationController and the height of UIBarButtonItem elements inside that bar.

Using a trick from this question I managed to change the height of navigation bar but I can see no way of adjusting the height of bar button items.

If anyone knows how to change the size of bar button items, please help me out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

乞讨 2024-12-25 08:56:50

这是我的解决方案。它运作得很好。

@interface UINavigationBar (CustomHeight)

@end

@implementation UINavigationBar (CustomHeight)

- (CGSize)sizeThatFits:(CGSize)size {
    // Change navigation bar height. The height must be even, otherwise there will be a white line above the navigation bar.
    CGSize newSize = CGSizeMake(self.frame.size.width, 40);
    return newSize;
}

-(void)layoutSubviews {
    [super layoutSubviews];

    // Make items on navigation bar vertically centered.
    int i = 0;
    for (UIView *view in self.subviews) {
        NSLog(@"%i. %@", i, [view description]);
        i++;
        if (i == 0)
            continue;
        float centerY = self.bounds.size.height / 2.0f;
        CGPoint center = view.center;
        center.y = centerY;
        view.center = center;
    }
}

This is my solution. It works very well.

@interface UINavigationBar (CustomHeight)

@end

@implementation UINavigationBar (CustomHeight)

- (CGSize)sizeThatFits:(CGSize)size {
    // Change navigation bar height. The height must be even, otherwise there will be a white line above the navigation bar.
    CGSize newSize = CGSizeMake(self.frame.size.width, 40);
    return newSize;
}

-(void)layoutSubviews {
    [super layoutSubviews];

    // Make items on navigation bar vertically centered.
    int i = 0;
    for (UIView *view in self.subviews) {
        NSLog(@"%i. %@", i, [view description]);
        i++;
        if (i == 0)
            continue;
        float centerY = self.bounds.size.height / 2.0f;
        CGPoint center = view.center;
        center.y = centerY;
        view.center = center;
    }
}
习ぎ惯性依靠 2024-12-25 08:56:50

也许这个关于自定义导航栏的教程会对您有所帮助:重新创建 iBooks 木质主题导航栏

如果您使用 UIImageView 创建一个 BarButtonItem ,您可能可以更改自定义 UIImageView 的框架大小/边界大小,

UIImageView* imageView = [[[UIImageView alloc] initWithFrame:navigationController.navigationBar.frame] autorelease];
imageView.contentMode = UIViewContentModeLeft;
imageView.image = [UIImage imageNamed:@"NavBar-iPhone.png"];
[navigationController.navigationBar insertSubview:imageView atIndex:0];

因此根据您的需要,您可以给出-initWithFrame 方法适当的值。

Maybe this tutorial about a customized navbar will help you: Recreating the iBooks wood themed navigation bar

If you create a BarButtonItem with a UIImageView you can maybe change the framesize/boundsize of the custom UIImageView

UIImageView* imageView = [[[UIImageView alloc] initWithFrame:navigationController.navigationBar.frame] autorelease];
imageView.contentMode = UIViewContentModeLeft;
imageView.image = [UIImage imageNamed:@"NavBar-iPhone.png"];
[navigationController.navigationBar insertSubview:imageView atIndex:0];

So for your need you would give the -initWithFrame method appropriate values.

堇色安年 2024-12-25 08:56:50
static CGFloat const CustomNavigationBarHeight = 74;


@implementation WTNavigationBar



- (CGSize)sizeThatFits:(CGSize)size{
    size.width = 1024;
    size.height = CustomNavigationBarHeight;
    return size;
}

-(void)layoutSubviews {
    [super layoutSubviews];
    for (UIView *view in self.subviews) {
        SFLog(@"view.class=%@",[view class]);
        if ([view isKindOfClass:NSClassFromString(@"UINavigationItemButtonView")]) {
            float centerY = self.bounds.size.height / 2.0f;
            CGPoint center = view.center;
            center.y = centerY;
            view.center = center;
        }
    }
}


@end

在我的 iPad 应用程序中,它具有固定的横向方向,我发现我必须对尺寸的宽度进行硬编码

static CGFloat const CustomNavigationBarHeight = 74;


@implementation WTNavigationBar



- (CGSize)sizeThatFits:(CGSize)size{
    size.width = 1024;
    size.height = CustomNavigationBarHeight;
    return size;
}

-(void)layoutSubviews {
    [super layoutSubviews];
    for (UIView *view in self.subviews) {
        SFLog(@"view.class=%@",[view class]);
        if ([view isKindOfClass:NSClassFromString(@"UINavigationItemButtonView")]) {
            float centerY = self.bounds.size.height / 2.0f;
            CGPoint center = view.center;
            center.y = centerY;
            view.center = center;
        }
    }
}


@end

in my iPad app,which has a fixed landscape orientation,I found I have to hardcode the size's width

尐偏执 2024-12-25 08:56:50

我设法通过子类化 UINavigationBar 并覆盖 -layoutSubviews 来完成类似的操作。代码如下所示:

-(void)layoutSubviews {
    [super layoutSubviews];
    int i = 0;
    for (UIView *view in self.subviews) {
        NSLog(@"%i. %@", i++, [view description]);
        if ([view isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
            view.frame = CGRectMake(0, 0, 100, 50);
        }
    }
}

如果您需要知道如何子类 UINavigationBar,请查看 这个非常好的答案

我不太确定 NSClassFromString(@"UINavigationButton")] 部分。它有效,但我这样做是作为一个实验,我不确定这是否会得到苹果的批准。我希望有更深入了解的人可以提供一些线索。

I managed to do something similar by subclassing UINavigationBar and overriding -layoutSubviews. The code looks like:

-(void)layoutSubviews {
    [super layoutSubviews];
    int i = 0;
    for (UIView *view in self.subviews) {
        NSLog(@"%i. %@", i++, [view description]);
        if ([view isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
            view.frame = CGRectMake(0, 0, 100, 50);
        }
    }
}

If you need to know how to subclass UINavigationBar, have a look at this very good answer.

I am not really sure about the NSClassFromString(@"UINavigationButton")] part. It works, but I did this as an experiment, and I'm not sure if this will get approved by Apple. I hope someone with a better knowledge might shed some light.

橙味迷妹 2024-12-25 08:56:50

对于 UINavigationbar

在 iOS SDK 4.3 及更高版本中,有一种方法(hack)可以更改 UINavigationBar 的高度。

要更改 UINavigationController 的高度,请在 viewWillAppear:animated: 函数中更改其框架大小。然后,高度将在整个应用程序中保持自定义。

对于 UIBarButtonItems
实际上我自己也遇到过这个问题,我唯一能想到的就是利用 initWithCustomView 并传入一个带有定义框架的 UIButton 。

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

/*
* Insert button styling
*/

button.frame = CGRectMake(0, 0, width, height);

UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];

否则 UIBarButtonItem 只有一个可以设置的宽度属性,但不幸的是没有高度属性。我用 initWithCustomView 做的另一件漂亮的事情是传递一个带有按钮和其他东西(如活动指示器)的工具栏。希望这有帮助。

For the UINavigationbar

In iOS SDK 4.3 and beyond, there is a way (hack) to change the height of the UINavigationBar.

To change the height of UINavigationController, change its frame size in viewWillAppear:animated: function. Then, the height will stay customized throughout whole app.

For the UIBarButtonItems
I've actually run into this myself and the only thing I could come up with was leveraging initWithCustomView and passing in a UIButton with a defined frame.

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

/*
* Insert button styling
*/

button.frame = CGRectMake(0, 0, width, height);

UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];

Otherwise UIBarButtonItem only has a width property that can be set but unfortunately not a height property. Another nifty thing I've done with initWithCustomView is to pass in a toolbar with a button and other things like activity indicators. Hope this helps.

不…忘初心 2024-12-25 08:56:50

你有多想要这个?而且,您想让您的导航栏有多薄(或多厚)?

一种方法是设置导航栏的变换以对其进行缩放和平移。如果你缩放太多,标题和按钮文本会看起来很奇怪,但如果你只需要削减几个像素,你可能会没事。

这是将其缩放为全高 75%(33 像素高)的结果:

在此处输入图像描述

以及代码产生这个:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.navigationItem.title = @"Thin Navigation Bar";

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle: @"Press Me" style:UIBarButtonItemStyleBordered target: nil action: NULL ] autorelease];

    CGFloat scale = .75;
    CGFloat cy = 44.0 - ( 44.0 * scale );

    self.navigationController.navigationBar.transform = CGAffineTransformScale( CGAffineTransformMakeTranslation( 0, -cy / 2.0 ), 1.0, scale )  ;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    CGFloat scale = .75;
    CGFloat cy = 44.0 - ( 44.0 * scale );

    CGRect r = self.view.frame;
    r.origin.y -= cy;
    r.size.height += cy;
    self.view.frame = r;
}

现在,这确实存在许多问题,这些问题可能可以解决,也可能无法解决。 #1 是您正在使用 UINavigationController 来调整导航栏和视图控制器视图的大小和位置。使用此技术的视图控制器之间的动画可能会看起来很奇怪。

我很好奇您是否可以解决相关问题...

最后一个想法:如果您不使用 UINavigationController 那么除了压扁文本之外,实际上没有太多问题。或者,您可以使用导航控制器,但隐藏默认导航栏,并将细导航栏添加到每个子视图控制器视图中。您甚至可以子类化 UINavigationBar 并从内部设置转换:

@interface TSThinNavBar : UINavigationBar
{
}
@end

@implementation TSThinNavBar

// assuming we'll always be constructed from a nib
- (id) initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder: aDecoder];
    if ( self != nil ) 
    {
        CGFloat scale = .75;
        CGFloat cy = 44.0 - ( 44.0 * scale );

        self.transform = CGAffineTransformScale( CGAffineTransformMakeTranslation( 0, -cy / 2.0 ), 1.0, scale )  ;
    }

    return self;
}

@end

How badly do you want this? And, how thin (or thick) do you want to make your navbar?

One approach would be to set the transform of the navbar to scale and translate it. If you scale it too much the title and button text will look wonky, but if you only need to shave a few pixels you might be allright.

Here's the result of scaling it to be 75% of full height (33 pixels tall):

enter image description here

And the code that produced this:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.navigationItem.title = @"Thin Navigation Bar";

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle: @"Press Me" style:UIBarButtonItemStyleBordered target: nil action: NULL ] autorelease];

    CGFloat scale = .75;
    CGFloat cy = 44.0 - ( 44.0 * scale );

    self.navigationController.navigationBar.transform = CGAffineTransformScale( CGAffineTransformMakeTranslation( 0, -cy / 2.0 ), 1.0, scale )  ;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    CGFloat scale = .75;
    CGFloat cy = 44.0 - ( 44.0 * scale );

    CGRect r = self.view.frame;
    r.origin.y -= cy;
    r.size.height += cy;
    self.view.frame = r;
}

Now, this does have a number of problems, which may or may not be solvable. #1 is that you're fighting with the UINavigationController to size and position the navbar and the view-controller views. Animating between view controllers that use this technique is likely going to look weird.

I'd be curious if you could solve the related issues...

One last thought: If you dont use a UINavigationController then there really aren't a whole lot of issues with this other than squished text. Or, you could use a navigation controller but hide the default navbar, and add the thin navbar to each of your child-view controller views. You could even subclass UINavigationBar and set the transform from within:

@interface TSThinNavBar : UINavigationBar
{
}
@end

@implementation TSThinNavBar

// assuming we'll always be constructed from a nib
- (id) initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder: aDecoder];
    if ( self != nil ) 
    {
        CGFloat scale = .75;
        CGFloat cy = 44.0 - ( 44.0 * scale );

        self.transform = CGAffineTransformScale( CGAffineTransformMakeTranslation( 0, -cy / 2.0 ), 1.0, scale )  ;
    }

    return self;
}

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文