UINavigationBarで左右のUIBarButtonItemの空のスペースを編集する方法[iOS7]


84

以前はiOS6.1を使用していましたが、現在はiOS 7に移行しています。他の問題に加えて、ナビゲーションバーで、左のバーボタンアイテムの左側のスペースと右側のボタンバーアイテムの右の空きスペースがかなりあることがわかりました。 iOS6よりもIOS7の方が多くなります。

ナビゲーションバーの左右のバーボタン項目の空きスペースを減らす方法はありますか?

前もって感謝します。


2
これを試してください:github.com/devxoul/UINavigationItem-Margin
devxoul

@ devxoul、UINavigationItem-マージンにiOS14の問題があります。私はそのための問題を作成しました。解決策がある場合は、これを調べてください。
kuldeep

回答:


222

私もこの問題に直面していました。また、iOS7の方がスペースが広いと感じています。そして、これは約10ポイント多いことがわかりました。私は通常LeftBarItemButton、端から始めたいときに負のスペースを使用します。これはあなたにも役立ちます。

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];

4
これはiOS7で実際に機能しています。現在、いくつかのプロジェクトでこれを使用しています...ポイントシステムに違いがあるため、注意する必要があります...
Adnan Aftab 2013

10
[NSArray arrayWithObjects:requiredButton、negativeSpacer]を実行すると機能しません。注文に注意してください。
Mert Buran 2014年

3
うまく機能します。rightBarButtonItemsの場合、右マージンを変更する場合は、スペーサーを配列の最初のアイテムにする必要があることに注意してください
leonaka 2015年

1
@C_X for iPhone 6、-16マージンは機能していないようです。-20は正しいようです..これをすべてのiPhoneデバイスで正常に機能させる方法はありますか?
Vignesh PT 2015

1
@ TheRohanSanap-正の幅は、最初のビジュアルアイテムの前にある空きスペースの量を増やすスペーサーになります。負の幅のこのトリックは、空きスペースを減らします。
toolmakerSteve 2017年

23

@C_Xの回答に基づいて、現在のデバイスのiOSバージョンに基づいてUIBarButtonItemを追加および配置するカテゴリを作成しました。

// 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が、ビュー間の遷移で問題が発生しました。


10

Swift 2.0の場合、これは次の効果を得るための私の解決策でした...

(実際の値は状況によって異なる場合があります)

ここに画像の説明を入力してください

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)


9

これは私の解決策ですSwift 3.0

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

6

このバグを修正するには、をUIButtonオーバーライドできるようにサブクラス化する必要がありますalignmentRectInsets。私のテストから、UIEdgeInsetsボタンの位置に応じて、正の右オフセットまたは正の左オフセットのいずれかでを返す必要があります。これらの数値は私には意味がありません(常識によれば、少なくとも1つは負である必要があります)が、これが実際に機能するものです。

- (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ます。


答えてくれてありがとう。それは良い解決策ですが、今はサブクラス化を避けようとしているので、@ C_Xの答えを好みました。–
Salman Zaidi

これにより、iOS 6のアニメーション中にボタンが奇妙にシフトしました。ボタンは間違った場所から始まり、アニメーションの完了後に挿入図に一致するようにシフトしていました。
クリスワグナー

私は驚かないでしょう。上記のコードは、iOS7ビルド用のiOS6スタイルのレイアウトを取得するためにのみ必要です。
jaredsinclair 2013年

クイックフィックス、いい仕事。しかし、iOSの9のために、あなたはそれらを設定していないインセットを返す必要がある:
A-Majeed

5

smekのリードに従って、カテゴリを作成しましたが、前方互換性ではなく後方互換性を提供するように変更しました。私はiOS7で希望どおりに動作するようにすべてをセットアップし、ユーザーがより低いものを実行している場合は、物事をいじり始めます。

@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

OSのバージョンを2回(INFViewControllerカテゴリで1回と繰り返し)チェックしていることに気付きました。これをプロジェクトのどこかで1回限りとして使用したい場合に備えて、カテゴリに残しました。


5

迅速にこれを行うことができます

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
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
この遅延と呼ばれる方法
orium

これはこれを行うための正確なソリューションであり、
iOS11

4

スウィフト3:

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

2

スウィフト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) 


1

ネゲティブスペースはiOS11からは機能しません

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]

1
「プライベートビューのレイアウトマージンを変更しようとしたクライアントエラー」
VladPulichev19年

0

UIButtonサブクラスでカスタムボタンを使用する必要があり、サブクラスでオーバーライドする必要があると思います-alignmentRectInsets。正しくシフトさせるために適切なエッジに正または負の値が必要かどうかを忘れていますが、一方が機能しない場合は、もう一方を試してください。


0

私のために働いた

rightBarButton.customView?.transform = CGAffineTransform(translationX:10、y:0)


-1

良い決断、どうもありがとう!ナビゲーションヘッダーの左側に2つの要素を追加する必要がありました。これが私の解決策です:

  // Settings Button
  // This trick correct spacing between two left buttons
  UIBarButtonItem *settingsButtonItem = [[UIBarButtonItem alloc] init];
  UIView *settingsButtonItemView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 22.0, 22.0)];
  settingsButtonItem.customView = settingsButtonItemView;
  UIButton *settingsButton = [UIButton buttonWithType:UIButtonTypeSystem];
  settingsButton.frame = settingsButtonItemView.frame;
  [settingsButton setImage:[UIImage imageNamed:@"settings"] forState:UIControlStateNormal];
  settingsButton.tintColor = [[[[UIApplication sharedApplication] delegate] window] tintColor];
  [settingsButton addTarget:self action:@selector(showSettings:) forControlEvents:UIControlEventTouchDown];
  [settingsButtonItemView addSubview:settingsButton];

  // Star Button
  UIBarButtonItem *starButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"star_gray"] style:UIBarButtonItemStyleBordered target:self action:@selector(showStarred)];
  starButtonItem.width = 22.0;
  NSLog(@"%f", starButtonItem.width);

  // Negative Spacer
  // It shifts star button to the left
  UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
  negativeSpacer.width = -10.0;

  NSArray *leftNavigtaionBarButtonItems = @[negativeSpacer, starButtonItem, settingsButtonItem];
  [self.navigationItem setLeftBarButtonItems:leftNavigtaionBarButtonItems];
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.