UINavigationBar'da Sol, Sağ UIBarButtonItem'in Boş Alanları Nasıl Düzenlenir [iOS 7]


84

Daha önce iOS 6.1 kullanıyordum, ancak şimdi iOS 7'ye geçtim. Diğer sorunların yanı sıra, gezinme çubuğumda sol çubuk düğme öğesinin sol boşluğu ve sağ düğme çubuğu öğesinin sağ boş alanının oldukça fazla olduğunu gözlemledim. IOS 7'de iOS 6'dan daha fazla.

Gezinme çubuğundaki sol, sağ çubuk düğme öğelerinin boş alanlarını azaltmanın bir yolu var mı?

Şimdiden teşekkürler.



@devxoul, UINavigationItem-Margin'in iOS14 ile sorunu var. Bunun için sorun yarattım, herhangi bir çözümünüz varsa lütfen buna bakın.
Kuldeep

Yanıtlar:


222

Ben de bu sorunla karşı karşıyaydım. Ayrıca iOS 7'de daha fazla alan olduğuna dair hislerim var. Ve bunun yaklaşık 10 puan daha fazla olduğunu anladım. LeftBarItemButtonKenardan başlamak istediğimde genellikle negatif boşluklar kullanırım . Bu sizin için de faydalı olabilir.

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
Şu anda birkaç projemde bunu kullandığım için gerçekten iOS 7'de çalışıyor ... Puan sisteminde fark var, bu yüzden bununla ilgilenmelisin ....
Adnan Aftab

10
[NSArray arrayWithObjects: requiredButton, negativeSpacer] yaparsanız çalışmaz. Düzene dikkat et.
Mert Buran

3
Harika çalışıyor ve sağ marjı değiştirmek istiyorsanız, rightBarButtonItems için boşluk bırakıcının dizideki ilk öğe olması gerektiğini unutmayın
leonaka

1
İPhone 6 için @C_X, -16 marjı işe yaramıyor gibi görünüyor. -20 doğru görünüyor .. Bunun tüm iPhone cihazlarında sorunsuz çalışmasını nasıl sağlayabileceğimiz hakkında bir fikriniz var mı?
Vignesh PT

2
İOS 13 için çalışmıyor! Bunu iOS 13'te nasıl başaracağını bilen var mı?
niku

23

@C_X'in cevabına dayanarak, mevcut cihazın iOS sürümüne göre UIBarButtonItem'i ekleyen ve konumlandıran bir kategori oluşturdum.

// 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

Görünüm denetleyicinizde artık [self.navigationItem addLeftBarButtonItem:leftBarButtonItem];ve[self.navigationItem addRightBarButtonItem:rightBarButtonItem];

Ayrıca alt sınıflandırma UIButtonve geçersiz kılmayı da denedim, -alignmentRectInsetsancak bu bana görüşler arasındaki geçişlerle ilgili sorunlar verdi.


10

Swift 2.0 için, aşağıdaki efekti elde etmek için bu benim çözümümdü ...

(durumunuza bağlı olarak gerçek değerler farklı olabilir)

görüntü açıklamasını buraya girin

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 GÜNCELLEME:

Swift 2.2 için action: Selectoryöntem değişti ve aşağıdaki gibi yazılması gerekiyor

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


9

Bu benim için çözümüm Swift 3.0:

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

6

Bu hatayı düzeltmek için, alt sınıfa geçmeniz gerekir, UIButtonböylece geçersiz kılabilirsiniz alignmentRectInsets. Testlerimden, UIEdgeInsetsdüğme konumuna bağlı olarak pozitif bir sağ ofset veya pozitif bir sol ofset ile a döndürmeniz gerekecek . Bu sayılar benim için bir anlam ifade etmiyor (en azından biri sağduyuya göre negatif olmalı), ama aslında işe yarayan şey bu:

- (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'e ayarlamayı denememi önerdiği için özel teşekkürler alignmentRectInsets.


Cevap için teşekkürler. İyi bir çözüm olmasına rağmen, @C_X cevabını tercih ettim çünkü şu anda alt sınıflardan kaçınmaya çalışıyorum ..
Salman Zaidi

Bu, iOS 6'daki animasyonlar sırasında düğmelerin garip bir şekilde değişmesine neden oldu, yanlış noktada başlayıp animasyon tamamlandıktan sonra eklerle eşleşecek şekilde kayıyorlardı.
Chris Wagner

Şaşırmam. Yukarıdaki kod yalnızca iOS 7 sürümleri için bir iOS 6 tarzı düzen elde etmek için gereklidir.
jaredsinclair

Hızlı Onarım, İyi iş. Ancak iOS 9 için, eklenmemiş ekleri iade etmeniz gerekir:
A-Majeed

5

Smek'in öncülüğünü takiben bir kategori yaptım ancak ileriye dönük uyumluluk yerine geriye dönük uyumluluk sağlamak için değiştirdim. Her şeyi iOS 7'de istediğim gibi çalışacak şekilde ayarlıyorum ve sonra kullanıcı daha düşük bir şey çalıştırıyorsa işleri karıştırmaya başlıyorum.

@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

Ve bunu küresel olarak elde etmek için UIViewController, tüm görüntü denetleyicilerimin miras aldığı ince bir alt sınıfa sahibim.

@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

İşletim sistemi sürümünü iki kez kontrol ettiğimin farkındayım ( INFViewControllerkategoride bir kez ve tekrar), bunu projenin herhangi bir yerinde bir defaya mahsus kullanmak istediğimde kategoride bıraktım.


5

hızlı için bunu yapabilirsin

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
bu yöntem gecikmeli olarak çağrıldı
orium

Bunu yapmak için doğru çözüm bu, negatif alan iOS 11'den çalışmayacak
Rafiqul Hasan

4

Swift 3:

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

2

Swift 3.1

Sol çubuk düğmesi öğesine negatif boşluk vermek için:

    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

Negatif alan iOS 11'den çalışmaz

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

Yukarıdaki kod, hem leftBarButtonItem hem de RightBarButtonItem kenar boşluğunu kaldıracaktır. Ekstra marj eklemeniz gerekiyorsa (Marjı kaldırdıktan sonra) aşağıdaki kodu ekleyin

    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
'Özel bir görünümün düzen kenar boşluklarını değiştirmeye çalışırken istemci hatası'
Vlad Pulichev

0

Bir UIButtonalt sınıfla özel bir düğme kullanmanız gerektiğine inanıyorum ve alt sınıfınızda geçersiz kılın -alignmentRectInsets. Doğru kenarın doğru kayması için pozitif veya negatif bir değere ihtiyacınız olup olmadığını unutuyorum, ancak biri işe yaramazsa diğerini deneyin.


0

benim için çalıştı

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


-1

Güzel karar, çok teşekkürler! Gezinme başlığının sol tarafına yalnızca iki öğe eklemem gerekiyordu. Bu benim çözümüm:

  // 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];
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.