Проблема визуально:

Logo is centered in the empty space, not in the navigationBar

Я безуспешно пытался поместить изображение в центр собственного кадра. Я также попытался центрировать его, играя x CGRect, но безуспешно. Я предполагаю, что могу просто поместить пустой значок с тем же фоном, что и панель навигации; однако я не хочу этого делать. У меня может быть 2-3 иконки справа; и что?

    let image = UIImage(named: "some_logo")!
    let imageSize = CGSizeMake(60, 42)
    let marginX: CGFloat = (self.navigationController!.navigationBar.frame.size.width / 2) - (imageSize.width / 2)
    let imageView = UIImageView(frame: CGRect(x: marginX, y: 0, width: imageSize.width, height: imageSize.height))
    imageView.image = image
    imageView.contentMode = .ScaleAspectFit

    self.navigationItem.titleView = imageView

Я предпочитаю быстрый, но решения obj-c также приветствуются.

Любые указатели приветствуются.

Это приложение не имеет ничего общего с KIA, это просто какой-то логотип, который я вытащил из поиска Google, ища "какой-то логотип".

12
oyalhi 7 Янв 2016 в 09:06

7 ответов

Лучший ответ

Я создал расширение для решения этой проблемы, используя подсказку @idrougge.

Чтобы центрировать изображение представления заголовка независимо от того, какие кнопки у вас есть, представление содержимого устанавливается как представление заголовка, а затем представление изображения добавляется как дочерний элемент представления содержимого. Наконец, с использованием ограничений представление изображения выравнивается внутри своего родителя (представление содержимого).

import UIKit

extension UIViewController {

    func addLogoToNavigationBarItem() {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.heightAnchor.constraint(equalToConstant: <your_height>).isActive = true
        imageView.contentMode = .scaleAspectFit
        imageView.image = <your_image>
        //imageView.backgroundColor = .lightGray

        // In order to center the title view image no matter what buttons there are, do not set the
        // image view as title view, because it doesn't work. If there is only one button, the image
        // will not be aligned. Instead, a content view is set as title view, then the image view is
        // added as child of the content view. Finally, using constraints the image view is aligned
        // inside its parent.
        let contentView = UIView()
        self.navigationItem.titleView = contentView
        self.navigationItem.titleView?.addSubview(imageView)
        imageView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
        imageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
    }
}

Я надеюсь, что это помогает кому-то,

Хави

2
XME 25 Мар 2020 в 11:13

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

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

Надеюсь, это поможет.

0
F. Suyuti 6 Апр 2016 в 08:13

Как насчет того, чтобы установить центр вашего изображения равным navigationBar.center вместо установки поля?

//assuming we already have our navigationController
let myNicelLogoWidth = 100
let myNiceLogoHeight = 50
//start positioning your logo at 0.0, 0.0
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: myNicelLogoWidth, height: myNiceLogoHeight))
imageView.contentMode = .scaleAspectFit
imageView.center = navigationBar.center //the put your image at the center

let image = UIImage(named: "myNiceLogoImage")
imageView.image = image


navigationItem.titleView = imageView
1
Daniele 6 Ноя 2016 в 14:42

Была такая же проблема на телефонах меньшего размера. Изображение в заголовке перемещалось вправо. Вызывающая эту проблему кнопка возврата -> [back_button] [title_view]. Он центрируется, когда нет кнопки возврата или есть кнопка правой панели. Ричард Хоуп был прав, вам просто нужно сначала поставить UIView, а затем поставить UIImageView как subview. Программно это можно сделать так.

private var imageView: UIView {

    let bannerWidth = navigationBar.frame.size.width * 0.5 // 0.5 its multiplier to get correct image width
    let bannerHeight = navigationBar.frame.size.height

    let view = UIView()
    view.backgroundColor = .clear
    view.frame = CGRect(x: 0, y: 0, width: bannerWidth, height: bannerHeight)

    let image = UIImage(named: "your_image_name")
    let imageView = UIImageView(image: image)
    imageView.contentMode = .scaleAspectFit
    imageView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)

    view.addSubview(imageView)

    return view
}

Просто измените titleView

navigationItem.titleView = imageView
0
Владислав Шматок 29 Апр 2020 в 11:52

Самый простой способ сделать это - в Интерфейсном Разработчике.

Просто перетащите NavigationItem из библиотеки объектов и поместите его в свой ViewController, затем поместите UIView там, где идет заголовок (убедитесь, что вы установили фон на «очистить»). Затем поместите UIImageView в это представление и установите изображение в атрибутах. Инспектор на нужный образ. Соответственно масштабируйте свой UIImage и соответствующим образом устанавливайте свои ограничения.

10
Richard Hope 7 Май 2017 в 12:08

В заголовке вопроса указано «Swift / Obj-C», поэтому я использую код Obj-C:

UIImageView *titleImage = (UIImageView *)self.navigationItem.titleView;
titleImage = [[UIImageView alloc]initWithFrame:CGRectMake((self.navigationController.navigationBar.frame.size.width/2) - (100/2), 0, 100,self.navigationController.navigationBar.frame.size.height)];

//setting the image for UIImageView
titleImage.image = [UIImage imageNamed:@"someLogo"];
titleImage.contentMode = UIViewContentModeCenter;
self.navigationItem.titleView = titleImage;
2
Rajat 17 Июн 2016 в 06:19

Я столкнулся с той же проблемой. Затем я попробовал один код, показанный ниже.

 override func viewDidAppear(animated: Bool) {

    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
    imageView.contentMode = .ScaleAspectFit

    let image = UIImage(named: "googlePlus")
    imageView.image = image

    navigationItem.titleView = imageView
  }

Этот код работает нормально, когда я тестировал с помощью левой и правой кнопок панели.

Но в моем предыдущем коде нет кнопки правой панели.

Итак, изображение движется вправо.

Для решения этой проблемы я создал кнопку правой панели и изменил цвет оттенка на прозрачный.

Так что вроде все работает нормально. Это временное решение вашей проблемы.

13
Sudhi 9135 17 Июн 2016 в 06:14