Search code examples
iosobjective-cxcodeuinavigationcontrolleruibutton

iOS: Weird overlay on LeftBarButtonItem on Transition


I have a little problem using the navigation bar in an iOS project using objective-c.

I have some view controllers which are managed by a navigationviewcontroller, in a hierarchy like 1-2-3.

For the Viewcontrollers 2 and 3, I define custom back buttons in the viewWillAppear function, as I need to assign them a more complex logic when touching them. This is the reason why I do not set the back buttons in the previous view controller.

Everything works fine like this, my single problem is that, on transition from one view to another, the arrow of the back button is overlayed by a little view in the color of the navigation bar's background color until up to 50%, and then disappears when the transition has finished.

I create my back buttons in the navigationbar with this function, which is called in viewWillAppear:

- (void)setupCustomBackButton:(NSString *)title
                   action:(SEL)action
              buttonFrame:(CGRect)buttonFrame {

UIButton *backButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
backButton.frame = buttonFrame;
[backButton setImage:[UIImage imageNamed:@"backArrowOwn"] forState:UIControlStateNormal];
backButton.imageEdgeInsets = UIEdgeInsetsMake(0.0f, -8.0f, 0.0f, 0.0f);
[backButton setTitle:title forState:UIControlStateNormal];
[backButton.titleLabel setFont:[UIFont systemFontOfSize:17.0]];
backButton.titleEdgeInsets = UIEdgeInsetsMake(0.0f, -3.0f, 0.0f, 0.0f);
[backButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[backButton addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = barButton;
}

I hope that maybe someone has a good hint for me! Thanks!


Solution

  • After some long trying, I finally managed to save the problem on my own. So basically, when I create a leftBarButton, the button does not begin at the left margin, but has some space to the left margin. When I now inset my button image with a negative inset, the image will be basically outside my button frame. This portion is then weirdly overlayed on transition.

    To fix this, I just add another UIBarButtonItem additionally to my leftBarButtonItems. This seems to fix the issue for me, although I do not really know why exactly. Also, I think that it is weird that the leftBarButton in the navigationBar does not begin exactly at the margin, but has a space to the margin and I have to inset my image in order to get the exact same position for the image, as the default back button has.

    My new code for creating a custom back button now looks like this:

    - (void)setupCustomBackButton:(NSString *)title
                       action:(SEL)action
                  buttonFrame:(CGRect)buttonFrame {
    
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    backButton.frame = buttonFrame;
    [backButton setImage:[UIImage imageNamed:@"customBackArrow"] forState:UIControlStateNormal];
    backButton.imageEdgeInsets = UIEdgeInsetsMake(0.0f, -8.0f, 0.0f, 0.0f);
    [backButton setTitle:title forState:UIControlStateNormal];
    [backButton.titleLabel setFont:[UIFont systemFontOfSize:17.0]];
    backButton.titleEdgeInsets = UIEdgeInsetsMake(0.0f, -3.0f, 0.0f, 0.0f);
    [backButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
    [backButton addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    
    UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]
                                       initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace
                                       target:nil action:nil];
    
    self.navigationItem.leftBarButtonItem = nil;
    [self.navigationItem setLeftBarButtonItems:[NSArray arrayWithObjects:negativeSpacer,barButton, nil] animated:NO];
    }
    

    Thanks everyone and I hope that my answer helps anyone else too!