बाएं, खाली UIBarButtonItem के खाली स्थानों को संपादित करने के लिए UINavigationBar में [iOS 7]


84

मैं पहले iOS 6.1 का उपयोग कर रहा था, लेकिन अब मैं iOS 7 में चला गया हूं। अन्य समस्याओं के साथ, मैंने देखा है कि मेरे नेविगेशन बार में लेफ्ट बार बटन आइटम का लेफ्ट स्पेस और राइट बटन बार आइटम का राइट स्पेस खाली है। iOS 6 की तुलना में IOS 7 में अधिक।

मुझे यह जानने की जरूरत है कि नेविगेशन बार में बाएं, दाएं बार बटन आइटमों के खाली स्थानों को कैसे कम किया जा सकता है?

अग्रिम में धन्यवाद।


2
इसे आज़माएँ: github.com/devxoul/UINavigationItem-Margin
devxoul

@devxoul, UINavigationItem-Margin ने iOS14 के साथ इश्यू किया है। मैंने उसके लिए मुद्दा बनाया है यदि आपके पास कोई समाधान है तो कृपया इस पर गौर करें।
कुलदीप

जवाबों:


222

मैं भी इस समस्या का सामना कर रहा था। मेरी यह भी भावना है कि आईओएस 7 में अधिक जगह है। और मुझे पता चला कि यह लगभग 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
आईओएस 7 में वास्तव में काम कर रहा है, जैसा कि मैं अभी अपने दो प्रोजेक्ट्स में इसका उपयोग कर रहा हूं ... प्वाइंट सिस्टम में अंतर है, इसलिए आपको इस बात का ध्यान रखना होगा ....
अदनान आफताब

10
यह काम नहीं करता है अगर आप [NSArray arrayWithObjects: आवश्यकबटन, नेगेटिव स्पेसर]। आदेश को ध्यान में रखें।
मर्ट बुरन

3
महान काम करता है, और ध्यान दें कि rightBarButtonItems के लिए स्पेसर सरणी में पहला आइटम होना चाहिए यदि आप सही मार्जिन बदलना चाहते हैं
leonaka

1
IPhone 6 के लिए @C_X, -16 मार्जिन काम नहीं करता है। -20 सही लगता है। कोई भी विचार है कि हम सभी iPhone उपकरणों में इस काम को कैसे ठीक बना सकते हैं?
विग्नेश पीटी

1
@ TheRohanSanap - एक सकारात्मक चौड़ाई एक स्पेसर होगी जो पहले दृश्य आइटम से पहले कितना खाली स्थान बढ़ाती है। एक नकारात्मक चौड़ाई की इस चाल से खाली जगह कम हो जाती है।
टूलमेकरसेव

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

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)

स्विफ्ट 2.2 अद्यतन:

स्विफ्ट 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बटन स्थिति के आधार पर या तो एक सकारात्मक दाएं ऑफसेट या एक सकारात्मक बाएं ऑफसेट के साथ वापस लौटना होगा । ये संख्या मेरे लिए कोई मतलब नहीं है (कम से कम उनमें से एक नकारात्मक होना चाहिए, सामान्य ज्ञान के अनुसार), लेकिन यह वही है जो वास्तव में काम करता है:

- (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 उत्तर को प्राथमिकता दी है क्योंकि अभी मैं सब-क्लासिंग से बचने की कोशिश कर रहा हूँ ..
सलमान जैदी

इससे मुझे आईओएस 6 में एनिमेशन के दौरान बटन के कुछ अजीब बदलाव हो गए, वे गलत स्थान पर शुरू हो गए और एनीमेशन पूरा होने के बाद इनसेट से मिलान करने के लिए शिफ्ट हो गए।
क्रिस वैगनर

मुझे आश्चर्य नहीं होगा। उपरोक्त कोड को केवल iOS 7 बिल्ड के लिए iOS 6 स्टाइल लेआउट प्राप्त करने की आवश्यकता है।
jaredsinclair

जल्दी ठीक, अच्छा काम। हालाँकि iOS 9 के लिए, आपको इनसेट्स को सेट नहीं करने के लिए लौटाना होगा:
A-Majeed

5

स्मेक के नेतृत्व के बाद मैंने एक श्रेणी बनाई लेकिन इसे आगे की बजाय पीछे की संगतता प्रदान करने के लिए संशोधित किया। मैं सब कुछ काम करने के लिए सेटअप करता हूं कि मैं इसे 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

स्विफ्ट के लिए आप ऐसा कर सकते हैं

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
इस विधि को विलंब के साथ बुलाया गया
ओरियम

यह करने के लिए सटीक समाधान है, नकारात्मक स्थान iOS 11 से काम नहीं करेगा
रफीकुल हसन

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

IOS 11 से नेगेटिव स्पेस काम नहीं करेगा

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

ऊपर दिए गए कोड के दोनों ओर से बाईं ओर से हटा दिया जाएगा BBBBtontonItem और 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
'क्लाइंट त्रुटि एक निजी दृश्य के लेआउट मार्जिन को बदलने की कोशिश कर रही है'
व्लादि पुलिचव

0

मेरा मानना ​​है कि आपको UIButtonउपवर्ग के साथ कस्टम बटन का उपयोग करने की आवश्यकता है , और आपके उपवर्ग में, ओवरराइड करें -alignmentRectInsets। मैं भूल जाता हूं कि क्या आपको सही शिफ्ट के लिए सकारात्मक या नकारात्मक मूल्य की आवश्यकता है ताकि इसे सही ढंग से शिफ्ट किया जा सके, लेकिन अगर कोई काम नहीं करता है, तो दूसरे को आज़माएं।


0

मेरे लिए काम किया

rightBarButton.customView? .transform = CGAffineTransform (अनुवाद: 10, y: 0)


-1

अच्छा निर्णय, बहुत बहुत धन्यवाद! मुझे नेविगेशन हेडर के बाईं ओर सिर्फ दो तत्वों को जोड़ने की आवश्यकता थी। यह मेरा समाधान है:

  // 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];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.