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

Невозможно установить titleView в центре панели навигации, потому что кнопка возврата

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

Раньше я решил эту проблему с помощью поддельных кнопок на панели, поэтому я попытался добавить поддельную кнопку панели справа (и слева), но это не помогло.

- (void) searchButtonNavBar {


    CGRect imageSizeDummy = CGRectMake(0, 0, 25,25);

    UIButton *dummy = [[UIButton alloc] initWithFrame:imageSizeDummy];

    UIBarButtonItem
    *searchBarButtonDummy =[[UIBarButtonItem alloc] initWithCustomView:dummy];
    self.navigationItem.rightBarButtonItem = searchBarButtonDummy;

}


- (void)setNavBarLogo {

    [self setNeedsStatusBarAppearanceUpdate];
    CGRect myImageS = CGRectMake(0, 0, 44, 44);
    UIImageView *logo = [[UIImageView alloc] initWithFrame:myImageS];
    [logo setImage:[UIImage imageNamed:@"color.png"]];
    logo.contentMode = UIViewContentModeScaleAspectFit;
    self.navigationItem.titleView = logo;
    [[UIBarButtonItem appearance] setTitlePositionAdjustment:UIOffsetMake(0.0f, 0.0f) forBarMetrics:UIBarMetricsDefault];

}

Я думаю, что это должно работать нормально, потому что в этом случае titleView имеет кнопки на одной стороне. Есть ли какие-либо объяснения, почему он работал с кнопками на панели, которые были созданы программно, но не работает с общей кнопкой "Назад"?

4b9b3361

Ответ 1

UINavigationBar автоматически центрирует его titleView, пока есть достаточно места. Если заголовок не центрирован, это означает, что представление заголовка слишком велико для центрирования, и если вы установите backgroundColor, если ваш UIImageView, вы увидите, что именно это происходит.

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

Две возможные исправления:

  • Изображение, которое вы используете, слишком велико. Используйте изображение размером 44x44 точек с размером в 2x и 3 раза.

  • Оберните UIImageView внутри обычного UIView, чтобы избежать изменения размера.

Пример:

UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"test.jpeg"]];
imageView.contentMode = UIViewContentModeScaleAspectFit;

UIView* titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
imageView.frame = titleView.bounds;
[titleView addSubview:imageView];

self.navigationItem.titleView = titleView;

Ответ 2

Пример в версии Swift 3 Даррена второй путь:

let imageView = UIImageView(image: UIImage(named: "test"))
    imageView.contentMode = UIViewContentMode.scaleAspectFit
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
    imageView.frame = titleView.bounds
    titleView.addSubview(imageView)

self.navigationItem.titleView = titleView

Ответ 3

Не используйте titleView.

Просто добавьте свое изображение в navigationController.navigationBar

CGRect myImageS = CGRectMake(0, 0, 44, 44);
UIImageView *logo = [[UIImageView alloc] initWithFrame:myImageS];
[logo setImage:[UIImage imageNamed:@"color.png"]];
logo.contentMode = UIViewContentModeScaleAspectFit;
logo.center = CGPointMake(self.navigationController.navigationBar.width / 2.0, self.navigationController.navigationBar.height / 2.0);
logo.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
[self.navigationController.navigationBar addSubview:logo];

Ответ 4

Я предлагаю вам переопределить фреймворк функции - (void) setFrame: (CGRect) например:

- (void)setFrame:(CGRect)frame  { 

    [super setFrame:frame]; //systom function

    self.center = CGPointMake(self.superview.center.x, self.center.y);   //rewrite function 

}

чтобы titleView.center всегда находился в правильном расположении

Ответ 5

Qun Li отлично работал у меня. Здесь быстрый код 2.3:
override var frame: CGRect {
    set(newValue) {
        super.frame = newValue

        if let superview = self.superview {
            self.center = CGPoint(x: superview.center.x, y: self.center.y)
        }
    }

    get {
        return super.frame
    }
}

Ответ 6

Если вы используете пользовательский вид из наконечника, обязательно отключите автоматическую компоновку файла nib.

Ответ 7

1) Вы можете попробовать настроить изображение как фоновое изображение UINavigationBar, вызвав

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"color.png"] forBarMetrics:UIBarMetricsDefault];

внутри метода viewDidLoad.

Таким образом, он будет всегда центрирован, но если у вас есть кнопка back с длинным заголовком в качестве элемента навигации слева, она может отображаться поверх вашего логотипа. И сначала вы должны создать другое изображение с тем же размером, что и панель навигации, затем нарисуйте свое изображение в центре и после этого установите его как фоновое изображение.

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

Ответ 8

Я создал пользовательский UINavigationController, который после того, как вы вошли, вам нужно только позвонить showNavBarTitle(title:font:), если вы хотите показать, и removeNavBarTitle(), если вы хотите скрыть:

class NavigationController: UINavigationController {

    private static var mTitleFont = UIFont(name: <your desired font (String)> , size: <your desired font size -- however, font size will automatically adjust so the text fits in the label>)!
    private static var mNavBarLabel: UILabel = {

        let x: CGFloat = 60
        let y: CGFloat = 7
        let label = UILabel(frame: CGRect(x: x, y: y, width: UIScreen.main.bounds.size.width - 2 * x, height: 44 - 2 * y))

        label.adjustsFontSizeToFitWidth = true
        label.minimumScaleFactor = 0.5
        label.font = NavigationController.mTitleFont
        label.numberOfLines = 0
        label.textAlignment = .center

        return label
    }()

    func showNavBarLabel(title: String, font: UIFont = mTitleFont) {
        NavigationController.mNavBarLabel.text = title
        NavigationController.mNavBarLabel.font = font
        navigationBar.addSubview(NavigationController.mNavBarLabel)
    }

    func removeNavBarLabel() {
        NavigationController.mNavBarLabel.removeFromSuperview()
    }
}

Я нахожу лучшее место для вызова showNavBarTitle(title:font:) и removeNavBarTitle() в методах контроллера viewWillAppear() и viewWillDisappear() соответственно:

class YourViewController: UIViewController {

    func viewWillAppear() {
        (navigationController as! NavigationController).showNavBarLabel(title: "Your Title")
    }

    func viewWillDisappear() {
        (navigationController as! NavigationController).removeNavBarLabel()
    }
}

Ответ 9

В Swift это то, что сработало для меня, но это не лучшее решение (в основном, добавьте его в navigationBar):

    let titleIV = UIImageView(image: UIImage(named:"some"))
        titleIV.contentMode = .scaleAspectFit
        titleIV.translatesAutoresizingMaskIntoConstraints = false

      if let navigationController = self.navigationController{
            navigationController.navigationBar.addSubview(titleIV)
            titleIV.centerXAnchor.constraint(equalTo:  
navigationController.navigationBar.centerXAnchor).isActive = true
            titleIV.centerYAnchor.constraint(equalTo: navigationController.navigationBar.centerYAnchor).isActive = true
      }
      else{
            view.addSubview(titleIV)
            titleIV.topAnchor.constraint(equalTo: view.topAnchor, constant: UIApplication.shared.statusBarFrame.height).isActive = true
            titleIV.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true

      }

Ответ 10

Расширение ответа Даррена, исправление для меня состояло в том, чтобы вернуть sizeThatFits с размером UILabel. Оказывается, это вызывается после layoutSubViews, поэтому метка имеет размер.

override func sizeThatFits(_ size: CGSize) -> CGSize {
    return CGSize(width: titleLabel.frame.width + titleInset*2, height: titleLabel.frame.height)
}

Также обратите внимание, что у меня есть + titleInset*2, потому что Im устанавливает горизонтальные ограничения следующим образом:

titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: titleInset),
titleLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -titleInset)