UINavigationBar [iOS 7]에서 왼쪽, 오른쪽 UIBarButtonItem의 빈 공간을 편집하는 방법


84

이전에 iOS 6.1을 사용하고 있었는데 지금은 iOS 7로 이동했습니다. 다른 문제와 함께 내비게이션 바에서 왼쪽 막대 버튼 항목의 왼쪽 공간과 오른쪽 버튼 막대 항목의 오른쪽 빈 공간이 상당히 iOS 6보다 IOS 7에서 더 많습니다.

탐색 모음에서 왼쪽, 오른쪽 막대 단추 항목의 빈 공간을 줄일 수있는 방법이 있는지 알고 싶습니다.

미리 감사드립니다.


2
이것을 시도하십시오 : github.com/devxoul/UINavigationItem-Margin
devxoul

@devxoul, UINavigationItem-Margin에 iOS14에 문제가 있습니다. 나는 당신이 어떤 해결책을 가지고 있다면 그것에 대한 문제를 만들었습니다.
Kuldeep

답변:


222

나는 또한이 문제에 직면했다. 또한 iOS 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
제가 지금 제 두 프로젝트에서 이것을 사용하고 있기 때문에 그것은 정말 iOS 7에서 작동하고 있습니다 ... 포인트 시스템에 차이가 있으므로 당신은 그것을 처리해야합니다 ....
Adnan Aftab

10
[NSArray arrayWithObjects : requiredButton, negativeSpacer]를 수행하면 작동하지 않습니다. 순서에 유의하십시오.
Mert Buran 2014 년

3
큰, 당신은 오른쪽 여백을 변경하려면 rightBarButtonItems의 스페이서가 배열의 첫 번째 항목이어야합니다 작품
leonaka

1
@C_X for iPhone 6, -16 여백이 작동하지 않는 것 같습니다. -20이 맞는 것 같네요 .. 어떻게하면 모든 iPhone 장치에서 제대로 작동하는지 알 수 있습니까?
인 Vignesh PT

1
@TheRohanSanap-양수 너비는 첫 번째 시각적 항목 이전에 얼마나 많은 빈 공간이 있는지 를 증가 시키는 스페이서입니다 . 음의 폭이 트릭은 감소 빈 공간을.
ToolmakerSteve

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에서 버튼 위치에 따라 양의 오른쪽 오프셋 또는 양의 왼쪽 오프셋으로 a 를 반환해야합니다 . 이 숫자는 나에게 의미가 없지만 (상식에 따라 적어도 하나는 음수 여야 함) 실제로 작동하는 것은 다음과 같습니다.

- (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 응답이 있지만 지금 내가 피할 하위 클래스라는 것을 시도하고있다 .. 때문에
살만 자이

이로 인해 iOS 6에서 애니메이션을 실행하는 동안 버튼이 약간 이상하게 이동했습니다. 잘못된 지점에서 시작하여 애니메이션이 완료된 후 삽입물과 일치하도록 이동했습니다.
Chris Wagner

나는 놀라지 않을 것입니다. 위 코드는 iOS 7 빌드 용 iOS 6 스타일 레이아웃을 가져 오는 데만 필요합니다.
jaredsinclair 2013 년

빠른 수정, 잘하셨습니다. 그러나 iOS 9의 경우 설정하지 않은 삽입물을 반환해야합니다.
A-Majeed

5

smek의 리드에 따라 카테고리를 만들었지 만 앞으로가 아닌 하위 호환성을 제공하도록 수정했습니다. 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

나는 OS 버전을 두 번 ( 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
이러한 지연 호출 방법
orium

이것은이 작업을 수행하는 정확한 솔루션, 부정적인 공간은 아이폰 OS 11에서 작동하지 않습니다
Rafiqul 하산

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

Negetive 공간은 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]

1
'클라이언트 오류가 개인보기의 레이아웃 여백을 변경하려고'
블라드 Pulichev

0

나는 당신이 UIButton하위 클래스 와 함께 사용자 정의 버튼을 사용해야한다고 생각하고 하위 클래스에서 -alignmentRectInsets. 적절한 에지가 올바르게 이동하도록하려면 양수 또는 음수 값이 필요한지 잊어 버렸습니다.하지만 하나가 작동하지 않으면 다른 쪽을 시도하십시오.


0

나를 위해 일했다

rightBarButton.customView? .transform = CGAffineTransform (translationX : 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];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.