Подтвердить что ты не робот

IOS 7 Пользовательский UINavigationBar TitleView перемещается при нажатии или всплывании нового контроллера View

Я использую собственное представление заголовка для UINavigationBar со следующим кодом:

// Set a label to the nav bar
THLabel *titleLabel = [[THLabel alloc] init];
titleLabel.text = @"Test";
titleLabel.font = [UIFont fontWithName:APP_FONT size:22.0];
titleLabel.frame = CGRectMake(0, 0, 100, 30);
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.textColor = CUSTOM_LIGHT_BLUE;
titleLabel.strokeColor = kStrokeColor;
titleLabel.strokeSize = kStrokeSize;
self.navigationItem.titleView = titleLabel;

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

Смотрите видеоролик здесь: https://www.youtube.com/watch?v=961CCVQmpJM&feature=youtu.be

Я отключил автоматизацию каждого поднабора для навигационного контроллера как с раскадрой, так и с кодом для каждого контроллера вида:

    // Set the navigation bar hidded on the log in view
    UINavigationController* mainViewController = (UINavigationController*)self.appDelegate.window.rootViewController;
    [mainViewController setNavigationBarHidden:YES];
    [[mainViewController navigationBar] setAutoresizesSubviews:NO];

Однако он по-прежнему изменяется! Как я могу остановить это - что я делаю неправильно? Спасибо!

4b9b3361

Ответ 1

Он воспроизводится для меня, только если я помещаю в titleView код viewWillAppear. Перемещение его в viewDidLoad устраняет проблему

Ответ 2

Я бы вставлял метку внутри UIView. Интерфейс Builder не любит помещать непосредственно UILabel в titleView по какой-либо причине, которая может быть связана с вашей проблемой.

Также попробуйте установить autoResizingMask на UIViewAutoresizingFlexibleTopMargin. По моему опыту, любой пользовательский вид в барах ведет себя лучше таким образом.

Ответ 3

Это произошло и для меня. Две вещи, которые вы могли бы сделать:

1) убедитесь, что настройка навигации выполняется либо в viewDidLayoutSubviews, либо в viewDidLoad, как указано в приведенном выше ответе

2) У меня был элемент кнопки левой и правой строки в виде ноля, но вызывается только после того, как была установлена ​​метка заголовка. не забудьте установить элементы правой и левой строки в виде низа (если вы не используете их, конечно) перед установкой заголовка заголовка в заголовок.

Ответ 4

Развернув на @Alex Peda ответ выше, я нахожу, что на iOS7, вне viewDidLoad, как правило, минимальная ширина заголовка для пользовательского заголовка. Вот что я делаю, внизу. Обратите внимание, что в моем коде есть несколько методов, которые относятся к моему коду.

#define MAX_TITLE_WIDTH 400
#define MIN_TITLE_WIDTH 150

- (void) setNavBarTitle: (NSString *) newTitle;
{
    if (!newTitle) newTitle = @"";
    NSMutableString *title = [newTitle mutableCopy];

    if (![_titleView.text isEqualToString:title]) {

        NSAttributedString *attrTitle = [UIAppearance attributedString:title withFontType:FontTypeTitle | FontTypeBold | FontTypeItalic size: 40.0 andOtherAttributes:@{NSForegroundColorAttributeName: [UIColor blackColor]}];
        _titleView.attributedText = attrTitle;
        [_titleView sizeToFit];

        // In iOS7, if you set the nav bar title with a custom view outside of viewDidLoad, there appears to be a minimum title width. Narrower custom view titles are not centered properly. I'm working around this by centering the text in the label, and setting the width of the label to the minimum width.
        if ([Utilities ios7OrLater]) {
            if (_titleView.frameWidth < MIN_TITLE_WIDTH) {
                _titleView.textAlignment = NSTextAlignmentCenter;
                _titleView.frameWidth = MIN_TITLE_WIDTH;
            }
        }

        if (_titleView.frameWidth > MAX_TITLE_WIDTH) {
            _titleView.frameWidth = MAX_TITLE_WIDTH;
        }
    }

    self.navigationItem.titleView = _titleView;
}

Ответ 5

В моем случае это произошло, потому что я устанавливал UIBarButton перед titleView. Настройка titleView должна быть первой. Теперь работает отлично.

Ответ 6

То, что сработало для меня, было создание переменной в контроллере представления, которая содержит желаемый вид заголовка, а затем инициализирует его в viewDidLoad. Затем вы можете установить этот вид на self.navigationItem.titleView в viewWillAppear, и он должен отображаться правильно. Нет необходимости устанавливать autoResizeMask, или rightBarButtons и т.д.

Пример:

class ViewController {
    var myTitleImage: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        myTitleImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
        myTitleImage.contentMode = .scaleAspectFit
        myTitleImage.image = #imageLiteral(resourceName: "my_title_image")
        // etc...
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationItem.titleView = self.myTitleImage
    }    
}