iPhone - Как установить высоту uinavigationbar?

Я хочу сделать верхнюю часть окна навигации немного меньше. Как бы вы этого добились? Это то, что я пробовал до сих пор, но, как вы можете видеть, даже несмотря на то, что я делаю панель навигации меньше, область, которую она раньше занимала, все еще существует (черная).

[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];

альтернативный текст


person quano    schedule 25.01.2010    source источник
comment
Почему вы хотите изменить стандарт? Я думаю, вам следует разработать вид, чтобы он соответствовал оставшемуся пространству. Это нарушает [рекомендации по человеческому интерфейсу] [1]. [1]: developer.apple.com/iphone/library/documentation/UserExperience/   -  person Hoang Pham    schedule 25.01.2010
comment
Меня это больше беспокоит. Может, я хотел увеличить навигационную панель. Если я сделаю это сейчас, это покроет контент (в данном случае табличное представление).   -  person quano    schedule 25.01.2010
comment
Вы должны выбрать ответ - я бы предложил макросс, так как все другие простые ответы заставляют подпредставления перемещаться вниз.   -  person David H    schedule 10.12.2015


Ответы (9)


Создайте категорию UINavigationBar с нестандартным размером

@implementation UINavigationBar (customNav)
  - (CGSize)sizeThatFits:(CGSize)size {
    CGSize newSize = CGSizeMake(self.frame.size.width,70);
    return newSize;
  }
@end
person rnaud    schedule 07.10.2011
comment
Отличная находка! Может, лучше использовать то, что возвращает супер, а потом изменить свойство высоты? Изменить: только что понял, что не будет работать в категории, только в подклассе. - person aegzorz; 11.11.2011
comment
Для тех, кто хочет воспользоваться подходом, предложенным @aegzorz - использование подкласса не проблема, если использовать метод, предложенный Себастьяном Селисом в этой статье: sebastiancelis.com/2012/03/05/subclassing-hard-to-reach-classes - person Ivan Vučica; 25.09.2012
comment
Используйте подкласс вместо категории, здесь вы изменяете базовую реализацию, и любой код, использующий ее, потеряет базовую реализацию. Очень плохо ! - person nverinaud; 28.11.2013

Используя этот подкласс панели навигации, я успешно создал большую панель навигации на iOS 5.x - iOS 6.x на iPad. Это дает мне большую панель навигации, но не прерывает всю анимацию.

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
person mackross    schedule 28.11.2012
comment
Хорошее решение с трансформацией. Спасибо! У меня есть 2 альтернативы для получения представления фонового изображения в коде resetBackgroundImageFrame: 1, [self.subview objectAtIndex: 0] - мы можем с уверенностью предположить, что фоновый вид будет внизу стека - это фон, верно? 2, используйте KVO [self valueForKey: @backgroundView], это подход, который я решил использовать. - person Michal; 13.12.2012
comment
как применить этот подкласс? - person jturolla; 03.01.2013
comment
Метод initWithNavigationBarClass ... UINavigationController - person mackross; 04.01.2013
comment
Если вы загружаете UINavigationBar / UINavigationController из xib / раскадровки, вам нужно вместо этого переопределить - (id)initWithCoder:(NSCoder *)aDecoder. - person Kyle Fleming; 23.01.2013
comment
Это прекрасное решение. Я просто вставил это в свой собственный класс и запустил приложение; работает очень хорошо (iOS 6, еще не тестировалась на iOS 5). - person Mackey18; 23.04.2013
comment
Хорошее решение. Единственная проблема, с которой я сталкиваюсь, заключается в том, что перевод также применяется к фону. Есть идеи для такого поведения ..? - person konrad.bajtyngier; 28.05.2013
comment
Я с этим не сталкивался. На какой версии iOS это происходит? - person mackross; 09.06.2013
comment
Если вы загружаете из xib или раскадровки, выберите панель навигации в контроллере навигации и установите там подкласс. - person codepoet; 29.08.2014
comment
@mackross, тогда ... как мне установить rootViewController с контроллером навигации? Думаю, я не могу установить вместе класс панели навигации и контроллер корневого представления. - person Hemang; 04.07.2015

Для быстрого

создать подкласс Uinavigation bar.

import UIKit

class higherNavBar: UINavigationBar {

override func sizeThatFits(size: CGSize) -> CGSize {
    var newSize:CGSize = CGSizeMake(self.frame.size.width, 87)
    return newSize
}

С обеих сторон будут две пустые полоски, я изменил ширину на точное число, чтобы она работала.

Однако заголовок и кнопка возврата выровнены по нижнему краю.

person Chen Lu    schedule 14.01.2015
comment
Однако заголовок и кнопка возврата выровнены по нижнему краю, какое решение для них? - person Khurram Shehzad; 11.01.2017

Создавать подклассы UINavigationBar необязательно. В Objective-C вы можете использовать категорию, а в Swift - расширение.

extension UINavigationBar {
    public override func sizeThatFits(size: CGSize) -> CGSize {
        return CGSize(width: frame.width, height: 70)
    }
}
person Douglas Ferreira    schedule 27.06.2016

Я обнаружил, что следующий код лучше работает на iPad (и iPhone):

- (CGSize)sizeThatFits:(CGSize)size
{
     return CGSizeMake(self.superview.bounds.size.width, 62.0f);
}
person Foti Dim    schedule 06.02.2015

Если вы хотите использовать настраиваемую высоту для панели навигации, я думаю, вам, вероятно, следует, по крайней мере, использовать настраиваемую панель навигации (а не одну в вашем контроллере навигации). Скройте панель navController и добавьте свою. Затем вы можете установить для него любую высоту.

person Ben Gottlieb    schedule 25.01.2010
comment
Установка высоты не была проблемой, более того, в этом случае содержимое (табличное представление), похоже, не меняет своего положения, когда панель навигации меняет свой размер. Как добавление моей пользовательской панели навигации повлияет на контент? - person quano; 25.01.2010
comment
Иерархия представлений NavController-with-navBar немного сложна. Есть родительское представление, navBar, а затем контент, хранящийся в представлении вашего контроллера представления. Если вы измените размер панели навигации, это не обязательно изменит размер представления вашего контроллера. Если ВЫ измените размер материала, вы сможете лучше контролировать то, что будет перетекать, чтобы оно соответствовало. - person Ben Gottlieb; 25.01.2010
comment
Я также обнаружил, что изменение размера панели навигации не работает в сочетании с UITableViews, UITabBarControllers и т. Д. Кажется, слишком многое жестко запрограммировано Apple. (Я попытался установить высоту tabBar в UINavigationControllerDelegate). - person benvolioT; 27.01.2011
comment
@Ben Gottlieb @benvolioT Итак, в заключение, теперь есть способ изменить высоту навигационной панели? - person aneuryzm; 19.06.2011
comment
Есть обновления по этому вопросу? У меня точно такая же проблема. Или пользовательский дизайн панели навигации должен быть 44 пикселя? - person Ryan Ye; 26.06.2011

Мне удалось использовать следующий код подкласса в Swift. Он использует существующую высоту в качестве отправной точки и добавляет к ней.

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

class TallBar: UINavigationBar {
    override func sizeThatFits(size: CGSize) -> CGSize {
        var size = super.sizeThatFits(size)
        size.height += 20
        return size
    }
}
person Matthew Wakefield    schedule 04.11.2015
comment
Единственная проблема в том, что кнопки заголовка и панели перемещаются вниз - все новое пространство находится вверху. - person David H; 10.12.2015
comment
Это правда, но в моем случае это было именно то, что я пытался сделать. Я поместил небольшой сегментированный элемент управления над панелью навигации, а сами кнопки оказались внизу. Но хороший улов - возможно, не лучшее решение, если кто-то пытался просто добавить место под существующей областью панели навигации. - person Matthew Wakefield; 10.12.2015
comment
Я только что получил решение @mackross, приведенное ниже, работающее в iOS9 (без использования изображений, но с теми же переопределениями). Мне нужно создать более высокую панель навигации с кнопками и заголовком в обычном положении. Я потратил на это большую часть утра (PITA). В любом случае, то, что у вас есть, - необходимая составляющая решения! - person David H; 10.12.2015
comment
Честное предупреждение - это решение больше не будет работать в iOS 11. - person Matthew Wakefield; 01.09.2017

Вот довольно хороший подкласс 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
    }
}
}
person Code Baller    schedule 17.12.2015

Я пока новичок в iOS. Я решил проблему следующим образом:

  1. Я создал новый класс, унаследованный от UINavigationBar

  2. Я отменяю следующий метод:

     (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)];


}
  1. В файле xib я изменил класс UINavigationBar панели навигации по умолчанию на свой класс.
person sudip    schedule 01.11.2012
comment
Это очень близко, однако он будет перекрывать основной вид вместо того, чтобы смещать его, чтобы выровняться с панелью навигации. - person rwyland; 08.03.2013