Изменить высоту элементов NavigationBar и UIBarButtonItem внутри него в Cocoa Touch - PullRequest
19 голосов
/ 27 ноября 2011

Полагаю, это не совсем соответствует рекомендациям Apple, но, наверное, это как-то возможно.Я хотел бы изменить высоту панели навигации внутри UINavigationController и высоту элементов UIBarButtonItem внутри этой панели.

Используя трюк из этот вопрос Мне удалось изменить высоту панели навигации, но я не вижу способа отрегулировать высоту элементов панели кнопок.

Если кто-нибудь знает, как изменить размер элементов панели кнопок, пожалуйста, помогите мне.

Ответы [ 6 ]

18 голосов
/ 13 сентября 2012

Это моё решение. Работает очень хорошо.

@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;
    }
}
16 голосов
/ 29 ноября 2011

Может быть, этот урок о настраиваемой панели навигации поможет вам: Воссоздание деревянной навигационной панели iBooks

Если вы создаете BarButtonItem с UIImageView, вы можете изменить размер рамки / границы пользовательского 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 соответствующие значения.

4 голосов
/ 22 мая 2013
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, которое имеет фиксированную альбомную ориентацию, я обнаружил, что должен жестко задавать ширину размера

3 голосов
/ 30 ноября 2011

Для UINavigationbar

В iOS SDK 4.3 и более поздних версиях есть способ (взлом) изменить высоту UINavigationBar.

Чтобы изменить высоту UINavigationController, измените его размер кадра в функции viewWillAppear:animated:. Затем высота будет оставаться неизменной на протяжении всего приложения.

Для элементов UIBarButton
Я на самом деле столкнулся с этим сам, и единственное, что я мог придумать, это использовать initWithCustomView и передать UIButton с определенным фреймом.

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

/*
* Insert button styling
*/

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

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

В противном случае UIBarButtonItem имеет только свойство width, которое можно установить, но, к сожалению, не свойство height. Еще одна изящная вещь, которую я сделал с initWithCustomView - это перейти на панель инструментов с кнопкой и другими вещами, такими как индикаторы активности. Надеюсь, это поможет.

3 голосов
/ 29 ноября 2011

Мне удалось сделать нечто подобное, создав подкласс 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")].Это работает, но я сделал это в качестве эксперимента, и я не уверен, будет ли это одобрено Apple.Я надеюсь, что кто-то с лучшими знаниями мог бы пролить свет.

2 голосов
/ 02 декабря 2011

Как сильно ты этого хочешь? И насколько тонким (или толстым) вы хотите сделать свою навигационную панель?

Один из подходов - установить преобразование панели навигации для масштабирования и преобразования. Если вы масштабируете его слишком сильно, текст заголовка и кнопки будет выглядеть странно, но если вам нужно только побрить несколько пикселей, вы можете быть в порядке.

Вот результат масштабирования до 75% от полной высоты (33 пикселя в высоту):

enter image description here

И код, который произвел это:

- (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
...