Shabir jan
Shabir jan

Reputation: 2427

Common BarButtonItems on NavigationBar

I have 10 ViewController which have NavigationBar and each VC have same 3 Barbutton items (1 on left and 2 on right). Right now I am adding same buttons in each of ViewController, so I have duplicated code in 10 controllers for same bar button items.

What will be the correct approach for such scenario. I have thought about using UIViewController as Base and add these BarButtonItem on NavigationBar, but with that path I have issue, as I am using Coordinator for navigations, and each of those 3 BarButtonItem navigate to other screens. Likewise i tried UIViewController extension as well, but still navigation problem is there.

Upvotes: 0

Views: 86

Answers (1)

VRAwesome
VRAwesome

Reputation: 4803

Objective C

Declare these methods in one common class, I have Utilities.h.

+ (NSArray *)setButtonWithTitle:(NSString *)title target:(id)target action:(SEL)action;
+ (NSArray *)setButtonWithImage:(NSString *)imgName target:(id)target action:(SEL)action;
+ (NSArray *)setTwoButtonWithTarget:(id)target action1:(SEL)action1 image1:(NSString *)imgName1 action2:(SEL)action2 image2:(NSString *)imgName2;

Then define those methods in respective files. As I have Utilities.m.

+ (NSArray *)setButtonWithTitle:(NSString *)title target:(id)target action:(SEL)action {

     UIBarButtonItem *negativeSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
     negativeSpace.width = -10;
     UIBarButtonItem *textBarButton = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:target action:action];

     NSArray *arrBarItems = [NSArray arrayWithObjects:negativeSpace, textBarButton, nil];
     return arrBarItems;
}

+ (NSArray *)setButtonWithImage:(NSString *)imgName target:(id)target action:(SEL)action {

     UIBarButtonItem *negativeSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    negativeSpace.width = -5;
     UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:imgName] style:UIBarButtonItemStylePlain target:target action:action];

    NSArray *arrBarItems = [NSArray arrayWithObjects:negativeSpace, backButton, nil];
     return arrBarItems;
}

+ (NSArray *)setTwoButtonWithTarget:(id)target action1:(SEL)action1 image1:(NSString *)imgName1 action2:(SEL)action2 image2:(NSString *)imgName2 {

     UIBarButtonItem *negativeSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    negativeSpace.width = -5;

     UIBarButtonItem *barButton1 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:imgName1] style:UIBarButtonItemStylePlain target:target action:action1];
    UIBarButtonItem *barButton2 = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:imgName2] style:UIBarButtonItemStylePlain target:target action:action2];

     NSArray *arrBarItems = [NSArray arrayWithObjects:negativeSpace, barButton2, barButton1, nil];
    return arrBarItems;
}

Tn above methods if you need more customisation to button, like bgcolor, titlecolor, etc. Then use UIButton and use it with barbuttonitem.

Now, in every ViewController, you just have to put only two lines, one for left button and one for right buttons.

self.navigationItem.leftBarButtonItems = [Utilities setButtonWithImage:@"ic_back" target:self action:@selector(goBackToPreviousView:)];
self.navigationItem.rightBarButtonItems = [Utilities setTwoButtonWithTarget:self action1:@selector(showSearchBar:) image1:@"ic_search" action2:@selector(showSortFilters:) image2:@"ic_sort"];

Swift

class Utilities {

    class func setButtonWith(title:String, target:Any, action:Selector) -> [UIBarButtonItem] {

        let negativeSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target:nil, action:nil)
        negativeSpace.width = -10;
        let textBarButton = UIBarButtonItem(title:title, style:UIBarButtonItem.Style.plain, target:target, action:action)

        let arrBarItems = [negativeSpace, textBarButton]
        return arrBarItems
    }

    class func setButtonWith(imgName: String, target:Any, action:Selector) -> [UIBarButtonItem] {

        let negativeSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target:nil, action:nil)
        negativeSpace.width = -5;
        let backButton = UIBarButtonItem(image:UIImage(named:imgName), style:UIBarButtonItem.Style.plain, target:target, action:action)

        let arrBarItems = [negativeSpace, backButton]
        return arrBarItems
    }

    class func setTwoButtonWith(target:Any, action1:Selector, imgName1:String, action2:Selector, imgName2:String)  -> [UIBarButtonItem] {

        let negativeSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target:nil, action:nil)
        negativeSpace.width = -5;

        let barButton1 = UIBarButtonItem(image:UIImage(named:imgName1), style:UIBarButtonItem.Style.plain, target:target, action:action1)
        let barButton2 = UIBarButtonItem(image:UIImage(named:imgName2), style:UIBarButtonItem.Style.plain, target:target, action:action2)

        let arrBarItems = [negativeSpace, barButton2, barButton1]
        return arrBarItems
    }
}

Wherever you need, just call it like :

self.navigationItem.leftBarButtonItems = Utilities.setButtonWith(imgName: "ic_back", target: self, action: #selector(goBackToPreviousView))
self.navigationItem.rightBarButtonItems = Utilities.setTwoButtonWith(target: self, action1: #selector(showSearchBar), imgName1: "ic_search", action2: #selector(showSortFilters), imgName2: 

Upvotes: 1

Related Questions