it-swarm.com.ru

Как редактировать пустые пространства слева, справа UIBarButtonItem в UINavigationBar [iOS 7]

Ранее я использовал iOS 6.1, но теперь я перешел на iOS 7. Наряду с другими проблемами, я заметил, что в моей панели навигации левый пробел элемента левой панели и правый пробел элемента правой кнопки панели довольно больше в IOS 7, чем в iOS 6.

Мне нужно знать, есть ли способ, как я могу уменьшить пустые места левых, правых кнопок на панели навигации?

Заранее спасибо.

79
Salman Zaidi

Я тоже столкнулся с этой проблемой. У меня также есть ощущение, что в iOS 7 больше места. И я понял, что это примерно на 10 баллов больше. Я обычно использую отрицательные пробелы, когда хочу, чтобы LeftBarItemButton начинался с Edge. Это может быть полезно и для вас.

UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];

negativeSpacer.width = -16; // it was -6 in iOS 6

[self.navigationItem setLeftBarButtonItems:@[negativeSpacer, requiredButton]; /* this will be the button which you actually need */] animated:NO];
217
Adnan Aftab

На основе @C_X его ответа я создал категорию, которая добавляет и позиционирует UIBarButtonItem на основе версии iOS текущего устройства.

// UINavigationItem+Additions.h
@interface UINavigationItem (Additions)
- (void)addLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem;
- (void)addRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem;
@end

// UINavigationItem+Additions.m
@implementation UINavigationItem (Additions)

- (void)addLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem
{
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        // Add a negative spacer on iOS >= 7.0
        UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
                              target:nil action:nil];
        negativeSpacer.width = -10;
        [self setLeftBarButtonItems:[NSArray arrayWithObjects:negativeSpacer, leftBarButtonItem, nil]];
    } else {
        // Just set the UIBarButtonItem as you would normally
        [self setLeftBarButtonItem:leftBarButtonItem];
    }
}

- (void)addRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem
{
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        // Add a negative spacer on iOS >= 7.0
        UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]
                                       initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
                                       target:nil action:nil];
        negativeSpacer.width = -10;
        [self setRightBarButtonItems:[NSArray arrayWithObjects:negativeSpacer, rightBarButtonItem, nil]];
    } else {
        // Just set the UIBarButtonItem as you would normally
        [self setRightBarButtonItem:rightBarButtonItem];
    }
}

@end

В вашем контроллере представления теперь вы можете использовать [self.navigationItem addLeftBarButtonItem:leftBarButtonItem]; и [self.navigationItem addRightBarButtonItem:rightBarButtonItem];

Я также попытался создать подкласс UIButton и переопределить -alignmentRectInsets, но это дало мне проблемы с переходами между представлениями.

23
smek

Для Swift 2.0 это было мое решение, чтобы получить следующий эффект ...

(фактические значения могут отличаться в зависимости от вашей ситуации)

 enter image description here

let captureButton = UIButton()
captureButton.setTitle("CAPTURE DETAILS", forState: .Normal)
captureButton.frame = CGRectMake(0, 0, 200, 95)
captureButton.addTarget(self, action: Selector("showCaptureDetailsForm:"), forControlEvents: .TouchUpInside) // *** See update below for Swift 2.2 syntax
captureButton.setBackgroundImage(UIImage(named: "blueTopRight"), forState: .Normal)

let rightBarButton = UIBarButtonItem()
rightBarButton.customView = captureButton        

let negativeSpacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
negativeSpacer.width = -25;

self.navigationItem.setRightBarButtonItems([negativeSpacer, rightBarButton ], animated: false)

Swift 2.2 ОБНОВЛЕНИЕ:

Для Swift 2.2 метод action: Selector изменился и должен быть напечатан следующим образом 

captureButton.addTarget(self, action: #selector(YourViewController.showCaptureDetailsForm(_:)), forControlEvents: .TouchUpInside)

10
Simon

Чтобы исправить эту ошибку, вы должны создать подкласс UIButton, чтобы можно было переопределить alignmentRectInsets. Из моего тестирования вам нужно будет вернуть UIEdgeInsets с положительным смещением вправо или с положительным смещением влево, в зависимости от положения кнопки. Эти числа не имеют смысла для меня (по крайней мере, один из них должен быть отрицательным, согласно здравому смыслу), но это то, что на самом деле работает:

- (UIEdgeInsets)alignmentRectInsets {
    UIEdgeInsets insets;
    if (IF_ITS_A_LEFT_BUTTON) {
        insets = UIEdgeInsetsMake(0, 9.0f, 0, 0);
    } 
    else { // IF_ITS_A_RIGHT_BUTTON
        insets = UIEdgeInsetsMake(0, 0, 0, 9.0f);
    }
    return insets;
}

Отдельное спасибо @zev за предложение попробовать alignmentRectInsets.

6
jaredsinclair

для Swift вы можете сделать это

var negativeSpace:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
negativeSpace.width = -17.0
self.navigationItem.rightBarButtonItems = [negativeSpace, requiredButton /* this will be the button which you actually need */]
5
reza pahlevi

Следуя примеру Смека я создал категорию, но изменил ее, чтобы обеспечить обратную совместимость, а не форварды. Я настраиваю все, чтобы работать так, как я хочу, в iOS 7, а затем, если пользователь запускает что-то более низкое, я начинаю гадить с вещами. 

@interface UINavigationItem (BarButtonItemSpacingSupport)

- (void)addLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem;
- (void)addRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem;

@end

@implementation UINavigationItem (BarButtonItemSpacingSupport)

- (void)addLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem
{
    if (SYSTEM_VERSION_LESS_THAN(@"7.0")) {
        // Add a spacer on when running lower than iOS 7.0
        UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
                                                                                        target:nil action:nil];
        negativeSpacer.width = 10;
        [self setLeftBarButtonItems:[NSArray arrayWithObjects:negativeSpacer, leftBarButtonItem, nil]];
    } else {
        // Just set the UIBarButtonItem as you would normally
        [self setLeftBarButtonItem:leftBarButtonItem];
    }
}

- (void)addRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem
{
    if (SYSTEM_VERSION_LESS_THAN(@"7.0")) {
        // Add a spacer on when running lower than iOS 7.0
        UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]
                                           initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
                                           target:nil action:nil];
        negativeSpacer.width = 10;
        [self setRightBarButtonItems:[NSArray arrayWithObjects:negativeSpacer, rightBarButtonItem, nil]];
    } else {
        // Just set the UIBarButtonItem as you would normally
        [self setRightBarButtonItem:rightBarButtonItem];
    }
}

@end

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

@interface INFViewController : UIViewController

@end

@implementation INFViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    if (SYSTEM_VERSION_LESS_THAN(@"7.0")) {
        [self setupNavBarForPreIOS7Support];
    }
}

- (void)setupNavBarForPreIOS7Support {
    if (self.navigationController) {
        UINavigationItem *navigationItem = self.navigationItem;
        UIBarButtonItem *leftItem = navigationItem.leftBarButtonItem;
        UIBarButtonItem *rightItem = navigationItem.rightBarButtonItem;

        if (leftItem) {
            [navigationItem addLeftBarButtonItem:leftItem];
        }

        if (rightItem) {
            [navigationItem addRightBarButtonItem:rightItem];
        }
    }
}

@end

Я понимаю, что я проверяю версию ОС дважды (один раз в INFViewController и снова в категории), я оставил ее в категории, если я хочу использовать ее как единовременную в любом месте проекта.

5
Chris Wagner

Свифт 3:

let negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
        negativeSpacer.width = -10
self.navigationItem.leftBarButtonItems = [negativeSpacer, yourBarButtonItem]
4
Dvole

Это мое решение для Swift 3.0:

rightBtn.imageInsets = UIEdgeInsets(top: 0, left: -13.0, bottom: 0, right: 13.0) self.navigationItem.rightBarButtonItem = rightBtn
4
tuandapen

Swift 3.1

Чтобы оставить отрицательный пробел на левой кнопке:

    let backButton = UIButton.init(type: .custom)
    backButton.frame = CGRect.init(x: 0, y: 0, width: 40, height: 40)
    // negative space
    backButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: -44.0, bottom: 0, right: 0)
    backButton.setImage(Ionicons.iosArrowBack.image(30, color: UIColor(hex: 0xFD6250)), for: .normal)
    backButton.addTarget(self, action: #selector(InviteVC.goBack), for: .touchUpInside)   
    // set back button
    self.navigationItem.leftBarButtonIteUIBarButtonItem.init(customView: backButton) 

2
rp2701
As of iOS 11 wont accept negative space width, in order to align the bar button items to the margin, I have used the below code.

 override func viewWillLayoutSubviews() {
                super.viewWillLayoutSubviews()
                for view in (self.navigationController?.navigationBar.subviews)! {
                    view.layoutMargins = UIEdgeInsets.zero
                }
            }
2
vinny

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

0
Zev Eisenberg

Негативное пространство не будет работать с iOS 11

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    // to remove navigation bar extra margin
    for view in (self.navigationController?.navigationBar.subviews)! {
        view.layoutMargins = UIEdgeInsets.zero
    }
}

Выше код удалит поля с обеих сторон leftBarButtonItem и RightBarButtonItem. Если вам нужно добавить дополнительную маржу (После удаления маржи), добавьте следующий код

    let rightButton = UIButton(frame: CGRect(x: 0, y: 0, width: 17, height: 20))
    rightButton.setImage(UIImage(named: "ic_cart"), for: .normal)

    let rightBarButtomItem = UIBarButtonItem(customView: rightButton)

    let spacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
    spacer.width = 28 //This will add extra margin on right side
    navigationItem.rightBarButtonItems = [spacer,rightBarButtomItem]
0
Rafiqul Hasan