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

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

Ответы [ 20 ]

2 голосов
/ 30 января 2018

В моем случае

  1. изменить рамку элемента barbuttonItem для настройки пробелов

  2. Добавить, удалить barButtonItems динамически.

  3. изменение цвета оттенка в зависимости от содержимого tableviewOffset.y

как это enter image description here enter image description here

enter image description here enter image description here

Если ваша минимальная цель - iOS 11, вы можете изменить кадры barButton в viewDidLayoutSubviews

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Change the navigationBar item frames
    if let customView = wishButton.customView?.superview {
        customView.transform = CGAffineTransform(translationX: 7.0, y: 0)
    }

    if let customView = gourmetCountButton.customView?.superview {
        customView.transform = CGAffineTransform(translationX: 9.0, y: 0)
    }
}

Но это работает только на iOS 11.

Я также пытался использовать fixedSpace. Но он не работал в нескольких элементах навигационной панели.

 let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
    space.width = -10

Итак, я изменил ширину customView для настройки горизонтального пространства.

Это один из моих классов barButtonItem

final class DetailShareBarButtonItem: UIBarButtonItem {

// MARK: - Value
// MARK: Public
***// Change the width to adjust space***
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 32.0, height: 30.0))

override var tintColor: UIColor? {
    didSet {
        button.tintColor = tintColor
    }
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setButton()
}

required override init() {
    super.init()
    setButton()
}


// MARK: - Function
// MARK: Private
private func setButton() {
    // Button
    button.setImage( #imageLiteral(resourceName: "navibarIcShare02White").withRenderingMode(.alwaysTemplate), for: .normal)
    button.tintColor              = .white
    button.imageEdgeInsets        = UIEdgeInsetsMake(0, 1.0, 1.0, 0)
    button.imageView?.contentMode = .scaleAspectFill

    let containerView = UIView(frame: button.bounds)
    containerView.backgroundColor = .clear
    containerView.addSubview(button)
    customView = containerView
}
}

Это результат.

Я тестировал на iOS 9 ~ 11, (Swift 4)

enter image description here

2 голосов
/ 22 августа 2017

Вот решение Адриано с использованием Swift 3. Это было единственное решение, которое мне помогло, и я попробовал несколько.

  let suggestImage  = UIImage(named: "menu.png")!
    let suggestButton = UIButton(frame: CGRect(x:0, y:0, width:34, height:20))
    suggestButton.setBackgroundImage(suggestImage, for: .normal)
    suggestButton.addTarget(self, action: #selector(self.showPopover(sender:)), for:.touchUpInside)
    suggestButton.transform = CGAffineTransform(translationX: 0, y: -8)
    // 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.leftBarButtonItem = suggestButtonItem
2 голосов
/ 13 апреля 2017

Свифт 3,1

let cancelBarButtonItem = UIBarButtonItem()
cancelBarButtonItem.setBackgroundVerticalPositionAdjustment(4, for: .default)
vc.navigationItem.setLeftBarButton(cancelBarButtonItem, animated: true)
2 голосов
/ 14 октября 2015

Как сказал @Anomie, нам нужно подкласс UINavigationBar, и переопределить layoutSubviews().

При этом все элементы кнопок правой панели будут прочно прикреплены к правой стороне панели навигации (в отличие от настройки по умолчанию немного левой) :

class AdjustedNavigationBar: UINavigationBar {

    override func layoutSubviews() {
        super.layoutSubviews()

        if let rightItems = topItem?.rightBarButtonItems where rightItems.count > 1 {
            for i in 0..<rightItems.count {
                let barButtonItem = rightItems[i]
                if let customView = barButtonItem.customView {
                    let frame = customView.frame
                    customView.frame = CGRect(x: UIApplication.sharedApplication().windows.last!.bounds.size.width-CGFloat(i+1)*44, y: frame.origin.y, width: frame.size.width, height: frame.size.height)
                }

            }
        }
    }
}

Единственное место для установки свойства UINavigationBar UINavigationController находится в его init (), например так:

let controllerVC = UINavigationController(navigationBarClass: AdjustedNavigationBar.self, toolbarClass: nil)
controllerVC.viewControllers = [UIViewController()]

Во второй строке задается контроллер корневого представления UINavigationController. (Поскольку мы не можем установить его с помощью init(rootViewController:)

1 голос
/ 19 января 2017

Вы всегда можете выполнить настройки, используя вкладки на кнопке. Например,

UIButton *toggleBtn =  [UIButton buttonWithType:UIButtonTypeCustom];
[toggleBtn setFrame:CGRectMake(0, 0, 20, 20)];
[toggleBtn addTarget:self action:@selector(toggleView) forControlEvents:UIControlEventTouchUpInside];

[toggleBtn setImageEdgeInsets:((IS_IPAD)? UIEdgeInsetsMake(0,-18, 0, 6) : UIEdgeInsetsMake(0, -3, 0, -3))];

UIBarButtonItem *toggleBtnItem = [[UIBarButtonItem alloc] initWithCustomView: toggleBtn];
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:searchBtnItem, toggleBtnItem, nil];

Это работает для меня.

1 голос
/ 17 января 2017

Инициализация UIBarButtonItem с настраиваемым представлением и перегрузкой layoutSubviews в настраиваемом представлении, например

-(void) layoutSubviews {
  [super layoutSubviews];
  CGRect frame = self.frame;
  CGFloat offsetY = 5;
  frame.origin.y = (44 - frame.size.height) / 2 - offsetY;
  self.frame = frame;
}
0 голосов
/ 28 марта 2019

Панель навигации с использованием изменения положения левой панели и вставок по краям изображения

Свифт 4

let leftBarButtonItem = UIBarButtonItem.init(image: UIImage(named:"ic_nav-bar_back.png"), landscapeImagePhone: nil, style: .plain, target: viewController, action: #selector(viewController.buttonClick(_:)))
            leftBarButtonItem.imageInsets = UIEdgeInsets(top: 0, left: -15, bottom: 0, right: 0)
            leftBarButtonItem.tintColor = UIColor(hex: 0xED6E19)
            viewController.navigationItem.setLeftBarButton(leftBarButtonItem, animated: true)
0 голосов
/ 13 февраля 2019

Аффинное преобразование может делать то, что вам нужно.В моем случае дизайнер дал мне иконку закрытия 16x16, и я хочу создать область нажатия 44x44.

closeButton.transform = CGAffineTransform(translationX: (44-16)/2, y: 0)
closeButton.snp.makeConstraints { make in
   make.size.equalTo(CGSize(width: 44, height: 44))
}
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: closeButton)
0 голосов
/ 12 сентября 2017

Я нашел решение этой проблемы, выполнив настройку во вкладках «Границы изображения» пользовательской кнопки.У меня в приложении было требование увеличить высоту панели навигации, и после увеличения высоты проблема с изображениями rightBarButtonItem и leftBarButtonItem была устранена.

Найдите приведенный ниже код: -

UIImage *image = [[UIImage imageNamed:@"searchbar.png"];
UIButton* searchbutton = [UIButton buttonWithType:UIButtonTypeCustom];
[searchbutton addTarget:self action:@selector(searchBar:) forControlEvents:UIControlEventTouchUpInside]; 
searchbutton.frame = CGRectMake(0,0,22, 22);
[searchbutton setImage:image forState:UIControlStateNormal];
[searchbutton setImageEdgeInsets:UIEdgeInsetsMake(-50, 0,50, 0)];
// Make BarButton Item
 UIBarButtonItem *navItem = [[UIBarButtonItem alloc] initWithCustomView:searchbutton];
self.navigationItem.rightBarButtonItem = navItem;

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 26 августа 2011

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

 UIButton *info = [UIButton buttonWithType:UIButtonTypeInfoLight];
 CGRect frame = info.frame;
 frame.size.width += 20;
 info.frame = frame;
 myNavigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]initWithCustomView:info]autorelease];
...