iOS7 excessive navigationbar button padding

后端 未结 6 678
天涯浪人
天涯浪人 2020-12-02 11:05

I\'m experiencing excessive UIBarButtonItem padding/spacing when using the LeftBarItems and RightBarItems (see image below). The icons used on the UIBarButtonItems do not co

相关标签:
6条回答
  • 2020-12-02 11:32

    I use this in order to remove space before the first item.

    However it doesn't work between system items like UIBarButtonSystemItemAdd, only with UIBarButtonItem that has an image.

    @interface UIBarButtonItem (NegativeSpacer)
    +(UIBarButtonItem*)negativeSpacerWithWidth:(NSInteger)width;
    @end
    @implementation UIBarButtonItem (NegativeSpacer)
    +(UIBarButtonItem*)negativeSpacerWithWidth:(NSInteger)width {
        UIBarButtonItem *item = [[UIBarButtonItem alloc]
                                 initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
                                 target:nil
                                 action:nil];
        item.width = (width >= 0 ? -width : width);
        return item;
    }
    @end
    

    Use it like this:


    UIBarButtonItem *item0 = [UIBarButtonItem negativeSpacerWithWidth:13];
    UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"sidebar.png"]
                                                              style:UIBarButtonItemStylePlain
                                                             target:vc
                                                             action:@selector(sideMenuAction:)];
    NSArray* items = @[item0, item1];
    [vc.navigationItem setLeftBarButtonItems:items animated:NO];
    [vc.navigationItem setLeftItemsSupplementBackButton:YES];
    
    0 讨论(0)
  • 2020-12-02 11:33

    You can move the image

    self.myBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 25, 0, -25);
    
    0 讨论(0)
  • 2020-12-02 11:41

    I solved this by using storybord interface.

    1.Select the Bar item.

    2.Select the Size Inspector.

    Here you can find image Inset,using top,bottom AND left , right you can change the position of Bar Item.

    0 讨论(0)
  • 2020-12-02 11:47

    Apple silently increased the horizontal spacing constraints for UIBarButtonItems and sadly, still hasn't added any UIAppearance methods to adjust the horizontal positioning of UIBarButtonItems.

    The best solution (which worked for me) is to wrap your UIBarButtonItems in a UIView using initWithCustomView: and adjust the bounds of that custom view to get your desired positioning. Here's a good answer on how to do this.

    If you want to take things a step further, you can create a category on UIBarButtonItem with class methods that return the bar buttons you use throughout your app. That way, when you a need a bar button, you can call something like:

    self.navigationItem.leftBarButtonItem = [UIBarButtonItem mySearchBarButtonItemWithTarget:self selector:@selector(search)];
    
    0 讨论(0)
  • 2020-12-02 11:48

    There are two kinds of button on the navigation bar in iOS 7: button with image and button with text. I wrote a class to do it. Here is how:

    GlobalUICommon.h:

    @interface UIBarButtonItem(CustomUIOfONE)
    
    + (UIBarButtonItem*)barItemWithImage:(UIImage*)image highlightedImage:(UIImage*)highlightedImage xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action;
    
    + (UIBarButtonItem*)barItemWithTitle:(NSString*)title xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action;
    
    @end
    

    GlobalUICommon.m:

    @implementation UIBarButtonItem(CustomUIOfONE)
    
    + (UIBarButtonItem*)barItemWithImage:(UIImage*)image highlightedImage:(UIImage*)highlightedImage xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action
    {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
        [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
        [button setImage:image forState:UIControlStateNormal];
        [button setImage:highlightedImage forState:UIControlStateHighlighted];
        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
            [button setImageEdgeInsets:UIEdgeInsetsMake(0, xOffset, 0, -xOffset)];
        }
    
        UIBarButtonItem *customUIBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
        return customUIBarButtonItem;
    }
    
    + (UIBarButtonItem*)barItemWithTitle:(NSString*)title xOffset:(NSInteger)xOffset target:(id)target action:(SEL)action
    {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setTitle:title forState:UIControlStateNormal];
        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
        [button.titleLabel setFont:[UIFont systemFontOfSize:15]];
        [button setFrame:CGRectMake(0, 0, [button.titleLabel.text sizeWithFont:button.titleLabel.font].width + 3, 24)];
        [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
            [button setContentEdgeInsets:UIEdgeInsetsMake(0, xOffset, 0, -xOffset)];
        }
    
        UIBarButtonItem *customUIBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
        return customUIBarButtonItem;
    }
    
    @end
    

    YourViewController.m:

    Example for Button with Image:

    UIBarButtonItem* leftButtomItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"yourImage"]
                                                       highlightedImage:[UIImage imageNamed:@"yourImage"]
                                                                xOffset:-11
                                                                 target:self
                                                                 action:@selector(yourHandler)];
    self.navigationItem.leftBarButtonItem = leftButtomItem;
    UIBarButtonItem* rightButtonItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"yourImage"]
                                                       highlightedImage:[UIImage imageNamed:@"yourImage"]
                                                                xOffset:11
                                                                 target:self
                                                                 action:@selector(yourHandler)];
    self.navigationItem.rightBarButtonItem = rightButtonItem;
    

    Example for Button with Text:

    self.navigationItem.leftBarButtonItem = [UIBarButtonItem barItemWithTitle:@"yourText" xOffset:-11 target:self action:@selector(yourHandler:)];
    self.navigationItem.rightBarButtonItem = [UIBarButtonItem barItemWithTitle:@"yourText" xOffset:11 target:self action:@selector(yourHandler:)];
    

    That's it.

    0 讨论(0)
  • 2020-12-02 11:56

    As @Luda comments, the solution is to

    self.myBarButtonItem.imageInsets = UIEdgeInsetsMake(0, 25, 0, -25);
    

    However, @andrrs also points a problem here when inset is large: the hit area. In this case,we have to implement a way to setHitTestEdgeInsets. Below is an category method:

    @implementation UIButton (Extensions)
    
    @dynamic hitTestEdgeInsets;
    
    static const NSString *KEY_HIT_TEST_EDGE_INSETS = @"HitTestEdgeInsets";
    
    -(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets {
        NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:@encode(UIEdgeInsets)];
        objc_setAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    -(UIEdgeInsets)hitTestEdgeInsets {
        NSValue *value = objc_getAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS);
        if(value) {
            UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets;
        }else {
            return UIEdgeInsetsZero;
        }
    }
    
    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
        if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) ||       !self.enabled || self.hidden) {
            return [super pointInside:point withEvent:event];
        }
    
        CGRect relativeFrame = self.bounds;
        CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets);
    
        return CGRectContainsPoint(hitFrame, point);
    }
    
    @end
    
    0 讨论(0)
提交回复
热议问题