Изменить позицию UIBarButtonItem в UINavigationBar - PullRequest
63 голосов
/ 23 апреля 2011

Как я могу изменить положение UIBarButtonItem в UINavigationBar?Я бы хотел, чтобы моя кнопка была примерно на 5 пикселей выше ее обычной позиции.

Ответы [ 20 ]

118 голосов
/ 23 сентября 2012

Этот код создает кнопку возврата для UINavigationBar с фоном изображения и пользовательской позицией. Хитрость заключается в создании промежуточного вида и изменении его границ.

UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backBtnImage = [UIImage imageNamed:@"btn-back"];
UIImage *backBtnImagePressed = [UIImage imageNamed:@"btn-back-pressed"];
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];
[backBtn setBackgroundImage:backBtnImagePressed forState:UIControlStateHighlighted];
[backBtn addTarget:self action:@selector(goBack) forControlEvents:UIControlEventTouchUpInside];
backBtn.frame = CGRectMake(0, 0, 63, 33);
UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 63, 33)];
backButtonView.bounds = CGRectOffset(backButtonView.bounds, -14, -7);
[backButtonView addSubview:backBtn];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backButtonView];
self.navigationItem.leftBarButtonItem = backButton;
37 голосов
/ 17 декабря 2014

Я решил использовать преобразование и пользовательский вид:

(Swift)

  // create the button
  let suggestImage  = UIImage(named: "tab-item-popcorn-on")!.imageWithRenderingMode(.AlwaysOriginal)
  let suggestButton = UIButton(frame: CGRectMake(0, 0, 40, 40))
  suggestButton.setBackgroundImage(suggestImage, forState: .Normal)
  suggestButton.addTarget(self, action: Selector("suggesMovie:"), forControlEvents:.TouchUpInside)

  // here where the magic happens, you can shift it where you like
  suggestButton.transform = CGAffineTransformMakeTranslation(10, 0)

  // add the button to a container, otherwise the transform will be ignored  
  let suggestButtonContainer = UIView(frame: suggestButton.frame)
  suggestButtonContainer.addSubview(suggestButton)
  let suggestButtonItem = UIBarButtonItem(customView: suggestButtonContainer)

  // add button shift to the side
  navigationItem.rightBarButtonItem = suggestButtonItem
34 голосов
/ 28 апреля 2011

Нет особенно хорошего способа сделать это. Лучше всего, если вам действительно нужно, это создать подкласс UINavigationBar и переопределить layoutSubviews для вызова [super layoutSubviews], а затем найти и изменить положение кнопки.

17 голосов
/ 12 июня 2012

Для тех из вас, кто разрабатывает для iOS 5, кто сталкивался с этим и был обескуражен ... Попробуйте что-то вроде этого:

float my_offset_plus_or_minus = 3.0f;

UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithTitle:@"title" 
                                                          style:UIBarButtonItemStyleDone
                                                          target:someObject action:@selector(someMessage)];

[item setBackgroundVerticalPositionAdjustment:my_offset_plus_or_minus forBarMetrics:UIBarMetricsDefault];
12 голосов
/ 18 октября 2013

Лучший способ заключается в создании подкласса вашего UINavigationBar, как описано здесь: https://stackoverflow.com/a/17434530/1351190

Вот мой пример:

#define NAVIGATION_BTN_MARGIN 5

@implementation NewNavigationBar

- (void)layoutSubviews {

    [super layoutSubviews];

    UINavigationItem *navigationItem = [self topItem];

    UIView *subview = [[navigationItem rightBarButtonItem] customView];

    if (subview) {

        CGRect subviewFrame = subview.frame;
        subviewFrame.origin.x = self.frame.size.width - subview.frame.size.width - NAVIGATION_BTN_MARGIN;
        subviewFrame.origin.y = (self.frame.size.height - subview.frame.size.height) / 2;

        [subview setFrame:subviewFrame];
    }

    subview = [[navigationItem leftBarButtonItem] customView];

    if (subview) {

        CGRect subviewFrame = subview.frame;
        subviewFrame.origin.x = NAVIGATION_BTN_MARGIN;
        subviewFrame.origin.y = (self.frame.size.height - subview.frame.size.height) / 2;

        [subview setFrame:subviewFrame];
    }
}

@end

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

6 голосов
/ 04 декабря 2012

Попробуйте код ниже,

UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:@"Logout" style:UIBarButtonItemStyleDone target:self action:nil];
[button setBackgroundVerticalPositionAdjustment:-20.0f forBarMetrics:UIBarMetricsDefault];
[[self navigationItem] setRightBarButtonItem:button];

Используется для изменения позиции y в этом коде. Измените значение 'y' (здесь оно равно -20.0f) в соответствии с вашими требованиями. Если значение положительное, оно опустится на позицию кнопки. Если значение отрицательное, оно повысит вашу позицию кнопки.

6 голосов
/ 14 декабря 2015

Мне нужно было установить мою кнопку более вправо. Вот как я это сделал, используя UIAppearance в Swift. Там также есть свойство вертикального положения, поэтому я думаю, что вы можете настроить его в любом направлении.

UIBarButtonItem.appearance().setTitlePositionAdjustment(UIOffset.init(horizontal: 15, vertical: 0), forBarMetrics: UIBarMetrics.Default)

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

4 голосов
/ 19 октября 2012

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

3 голосов
/ 26 апреля 2017
  • Swift 3
  • высота пользовательской панели навигации
  • без прыжка заголовка

Шаг 1: Установка позиции заголовка с помощью внешнего видаAPI.Например, в didFinishLaunchingWithOptions AppDelegate

UINavigationBar.appearance().setTitleVerticalPositionAdjustment(-7, for: .default)

Шаг 2: Подкласс UINavigationBar

class YourNavigationBar: UINavigationBar {

    let YOUR_NAV_BAR_HEIGHT = 60

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        return CGSize(width: UIScreen.main.bounds.width, 
                     height: YOUR_NAV_BAR_HEIGHT)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let navigationItem = self.topItem

        for subview in subviews {
            if  subview == navigationItem?.leftBarButtonItem?.customView ||
                subview == navigationItem?.rightBarButtonItem?.customView {
                subview.center = CGPoint(x: subview.center.x, y: YOUR_NAV_BAR_HEIGHT / 2)
            }
        }
    }
}
3 голосов
/ 12 августа 2013

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

Например, чтобы переместить кнопку на 14 пунктов влево:

UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, image.size.width + 14, image.size.height)];
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(-14, 0, image.size.width, image.size.height);
[button setImage:image forState:UIControlStateNormal];
[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
[containerView addSubview:button];

UIButton* button2 = [UIButton buttonWithType:UIButtonTypeCustom];
button2.frame = CGRectMake(0, 0, image.size.width + 14, image.size.height);
[button2 addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
[containerView addSubview:button2];

UIBarButtonItem* item = [[[self alloc] initWithCustomView:containerView] autorelease];
...