Как я могу изменить положение UIBarButtonItem в UINavigationBar? Я бы хотел, чтобы моя кнопка была примерно на 5 пикселей выше, чем ее нормальная позиция.
Изменение позиции UIBarButtonItem в UINavigationBar
Ответ 1
Нет особого способа сделать это. Лучше всего, если вы действительно должны подклассифицировать UINavigationBar и переопределить layoutSubviews
для вызова [super layoutSubviews]
, а затем найти и изменить положение кнопки.
Ответ 2
Этот код создает обратную кнопку для 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;
Ответ 3
Я решил использовать преобразование и пользовательский вид:
(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
Ответ 4
Для тех из вас, кто развивается для 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];
Ответ 5
Лучший способ заключается в подклассе вашего UINavigationBar, как описано здесь: fooobar.com/questions/64630/...
Вот мой пример:
#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
Попробуйте код ниже,
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) в соответствии с вашим требованием. Если значение положительное, оно будет вниз по позиции кнопки. Если значение отрицательное, оно будет содержать положение вашей кнопки.
Ответ 7
Мне нужно было установить, чтобы моя кнопка была более направлена вправо. Вот как я это сделал, используя UIAppearance в Swift. Там есть свойство вертикальной позиции, так что, я думаю, вы можете настроить в любом направлении.
UIBarButtonItem.appearance().setTitlePositionAdjustment(UIOffset.init(horizontal: 15, vertical: 0), forBarMetrics: UIBarMetrics.Default)
Это кажется мне гораздо менее инвазивным, чем обращение к кадру напрямую или добавление пользовательских subviews.
Ответ 8
Если вы просто используете изображение, а НЕ - хром по умолчанию, вы можете использовать скрытые вставки изображения (установленные в инспекторе размера) для перемещения изображения внутри UIBarButtonItem (удобно, потому что по умолчанию горизонтальное заполнение может привести к изображение находится дальше, чем вы хотите). Вы можете использовать вставки изображения, чтобы расположить изображение за пределами UIBarButtonItem, а также все окрестности левой кнопки можно скрыть, так что вам не нужно беспокоиться о том, чтобы он располагался рядом с нажмите цель. (по крайней мере, в пределах разумного.)
Ответ 9
Лучшее решение, которое я смог найти, - инициализировать 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];
Ответ 10
- Swift 3
- настраиваемая высота панели навигации
- без заголовка
Шаг 1: Задайте позицию заголовка, используя API-интерфейс Appearance. Например, в AppDelegate didFinishLaunchingWithOptions
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)
}
}
}
}
Ответ 11
Как сказал @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:)
Ответ 12
Swift 3.1
let cancelBarButtonItem = UIBarButtonItem()
cancelBarButtonItem.setBackgroundVerticalPositionAdjustment(4, for: .default)
vc.navigationItem.setLeftBarButton(cancelBarButtonItem, animated: true)
Ответ 13
Здесь решение Adriano с использованием 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
Ответ 14
В моем случае
-
изменить рамку barbuttonItem для настройки пробелов
-
Добавить, удалить barButtonItems динамически.
-
изменить оттенок цвета в табличном представлении contentOffset.y
Если ваша минимальная цель - 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)
Ответ 15
Init 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;
}
Ответ 16
Вы всегда можете выполнять настройки с помощью вставки на кнопке. Например,
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];
Это работает для меня.
Ответ 17
Вот простой способ, который был достаточным для моих нужд. Я добавил информационную кнопку с правой стороны UINavigationBar, но по умолчанию она слишком близко подходит к краю. Расширив ширину рамки, я смог создать дополнительный интервал, необходимый справа.
UIButton *info = [UIButton buttonWithType:UIButtonTypeInfoLight];
CGRect frame = info.frame;
frame.size.width += 20;
info.frame = frame;
myNavigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]initWithCustomView:info]autorelease];
Ответ 18
Я нашел решение этой проблемы, выполнив настройку в вкладках Image Edge в пользовательской кнопке. У меня было требование в приложении увеличить высоту панели навигации, и после увеличения высоты делает проблему 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;
Надеюсь, это поможет кому угодно.
Ответ 19
Аффинное преобразование может делать то, что вам нужно. В моем случае дизайнер дал мне иконку закрытия 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)
Ответ 20
Панель навигации с помощью изменения положения левой панели и вставок по краям изображения
Свифт 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)