Обработка вращения подкласса UINavigationBar с помощью кнопок

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

Затем подкласс добавляется на панель навигации View Controllers в раскадровке.

Это код внутри подкласса UINavigationBar:

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    UIImage *image = [[UIImage imageNamed: @"mainNavBar"] resizableImageWithCapInsets:UIEdgeInsetsMake(0,5,0,5)];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}

-(void)awakeFromNib {
    UIButton *leftButton = [[UIButton alloc]initWithFrame:CGRectMake(7.0f, 7.0f, 38.0f, 29.0f)];
    [leftButton setImage:[UIImage imageNamed:@"menuBarItem"] forState:UIControlStateNormal];
    [leftButton addTarget:nil action:@selector(menuItemPressed:) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:leftButton];
}

Проблема заключается в вращении устройства. У меня также есть код в appDidFinishLaunching, использующий API внешнего вида для дополнительной настройки:

// Custom Navigation Bar appearance setup
[[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                                                       [UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], UITextAttributeTextColor,
                                                       [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5],UITextAttributeTextShadowColor,
                                                       [NSValue valueWithUIOffset:UIOffsetMake(0, 1)],
                                                       UITextAttributeTextShadowOffset,nil]];
// Used to deal with the rotation of the nav bar when implemented outside of Navigation Controller
[[UINavigationBar appearance] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight];
[[UINavigationBar appearance] setContentMode:UIViewContentModeScaleAspectFit];
// Used to push the title down slightly when in Landscape and NavBar outside of Navigation Controller
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:2 forBarMetrics:UIBarMetricsLandscapePhone];

Когда устройство вращается, все работает правильно с точки зрения масштабирования полосы по высоте, как и ожидалось, от 44 до 32 пикселей. Однако кнопки по-прежнему отображаются за пределами панели. введите описание изображения здесь

Я просмотрел несколько других сообщений SO по этому поводу, но не могу понять, как это правильно выполнить: iPhone: UINavigationBar с кнопками - отрегулируйте высоту

Автоматическое изменение размера UINavigationBar

В идеале я не хочу иметь дело с автоматическим вращением в контроллере представления, потому что этот UINavigationBar повторно используется через большое количество виртуальных каналов. Добавление кода автоматической ротации означало бы, что это тоже может понадобиться каждому венчурному капиталу?

ИЗМЕНИТЬ - следующий ответ Если я изменю awakeFromNib, чтобы включить следующее:

UINavigationItem* ni = [[UINavigationItem alloc] initWithTitle:@"Test"];
    UIImage *menuBgImage = [UIImage imageNamed:@"menuBarItem"];
    UIBarButtonItem *b =[[UIBarButtonItem alloc] initWithImage:menuBgImage landscapeImagePhone:menuBgImage style:UIBarButtonItemStylePlain target:nil action:@selector(menuItemPressed:)];
    ni.leftBarButtonItem = b;
    self.items = @[ni];

У меня проблема с UIBarButtonItemStylePlain, разрушающим изображение: введите описание изображения здесь

Если я завершу предыдущую настройку с помощью initWithCustomView и использую leftButton из исходного кода. С помощью leftButton, использующего автоматическое изменение размера для высоты, я получаю плохо растянутое изображение в альбомной ориентации?

введите описание изображения здесь

ИЗМЕНИТЬ 2 - Дополнительное изображение для каждого ответа введите описание изображения здесь


person StuartM    schedule 03.05.2013    source источник
comment
Вы должны установить автоматическое изменение размера UIbButton, которое вы создаете в методе awakeFromNib, а также включить свойство autoresizesubviews для navigatonBar.   -  person fibnochi    schedule 03.05.2013
comment
Не могли бы вы подтвердить, как это сделать, в ответе?   -  person StuartM    schedule 03.05.2013
comment
*** Недопустимый тип свойства, c в селекторе вызова, _UIAppearance_setAutoresizesSubviews: при попытке установить '[[UINavigationBar appearance] setAutoresizesSubviews: YES];'   -  person StuartM    schedule 03.05.2013


Ответы (1)


[self addSubview:leftButton];

Это проблема. Это не то, как вы добавляете вещи в UINavigationBar! Вы должны начать с UINavigationItem и установить для его кнопок значение UIBarButtonItem. Элементы кнопок панели будут отрегулированы при изменении размера панели навигации.

Вот простой пример, с которого вы можете начать (можете использовать свой awakeFromNib):

UINavigationItem* ni = [[UINavigationItem alloc] initWithTitle:@"Test"];
UIBarButtonItem* b = [[UIBarButtonItem alloc] initWithTitle:@"Howdy"
    style:UIBarButtonItemStyleBordered
    target:self action:@selector(pushNext:)];
ni.leftBarButtonItem = b;
self.items = @[ni];

Однако обратите внимание, что это не сработает, если вы затем используете этот UINavigationBar как часть UINavigationController! Кнопка левой панели будет нажата navigationItem контроллера представления. Если это часть стандартного интерфейса навигации, просто попросите каждый контроллер навигации добавить элемент кнопки левой панели.

Также вы не должны реализовывать drawRect. Вместо этого установите фоновое изображение панели навигации.

person matt    schedule 03.05.2013
comment
Знаете ли вы больше о том, как начать с UINavigationItem, который недоступен по внешнему виду API? - person StuartM; 03.05.2013
comment
Я не понимаю, как получить доступ к UINavigationItem, созданному подклассом, из подкласса UINavigationBar. Пожалуйста, дайте мне знать любую другую информацию - person StuartM; 03.05.2013
comment
Вы также не используете addSubview API внешнего вида. Вы просто делаете это в подклассе. Поэтому я говорю, что вместо этого делайте это правильно: создайте UINavigationItem, установите его leftBarButtonItem и вставьте его на панель навигации. - person matt; 03.05.2013
comment
Спасибо, Мэтт. Как правильно это реализовать? Полностью через внешний вид API или части с подклассом тоже? Я не был уверен, как установить фон из подкласса, отличного от drawInRect, или вы хотите вместо этого установить фон в API внешнего вида? - person StuartM; 03.05.2013
comment
Это не имеет значения, поскольку у вас уже есть подкласс. Просто позвоните setBackgroundImage в свой awakeFromNib. - person matt; 03.05.2013
comment
Я заменил [image drawInRect ... на [self setBackgroundImage: image forBarMetrics: UIBarMetricsDefault]; а теперь фоновое изображение вообще не отображается? - person StuartM; 03.05.2013
comment
К сожалению, это не работает, фон не отображается ни в альбомной, ни в портретной ориентации. Что касается изменения размера кнопки, я отредактировал вопрос, указав больше информации о проблемах, с которыми я сейчас сталкиваюсь. - person StuartM; 03.05.2013
comment
Фон решается без переопределения drawRect и использования self setBackground ... в awakeFromNib. В частности, не переопределяющий drawRect заставляет его отображаться, но все же проблема с изменением размера - person StuartM; 03.05.2013
comment
Не используйте UIBarButtonItemStylePlain. Вы должны создать элемент кнопки панели с initWithCustomView, а представление должно быть UIImageView, содержащим ваше изображение. - person matt; 03.05.2013
comment
Да, это последняя часть моего редактирования выше. Я пробовал с initWithCustomView загружать либо UIButton, либо UIImageView, и оба имеют тот же эффект, что и на последнем снимке экрана выше. - person StuartM; 03.05.2013
comment
Установите contentMode представления изображения на что-нибудь получше, например, UIViewContentModeCenter. Это предотвратит растяжение изображения при изменении размера изображения. Возможно, вам придется поэкспериментировать с разными режимами, пока не выберете нужный ... :) - person matt; 03.05.2013
comment
спасибо, к сожалению, не очень повезло с этим. Я прошел через все варианты для contentMode, и все та же проблема. Изображение либо на снимке экрана, либо в полном исходном размере (так как оно портретное), что означает, что оно слишком велико для панели навигации: / - person StuartM; 03.05.2013
comment
Действительно? А как насчет UIViewContentModeScaleAspectFit? Следует сохранить правильное соотношение сторон, одновременно подогнав его под меньшую высоту. - person matt; 03.05.2013
comment
Я снова добавил изображение, показывающее код / ​​результат в вопрос - person StuartM; 03.05.2013
comment
Разве что это на самом деле правильное изображение с измененным размером ?? Выглядит немного странно и требует выравнивания сейчас ... Я добавил изменяемые размеры левого и верхнего полей, так что подумал, что они должны правильно разместиться на месте - person StuartM; 03.05.2013
comment
Принято в качестве ответа, поскольку решено не представлять эти виды в пейзаже, оказывается трудным для чего-то такого простого :). У меня проблемы с заголовком, но я подниму новый вопрос, спасибо за помощь @matt - person StuartM; 04.05.2013