Question

I have an app that has a reusable XIB for a view that is included in every view controller of the app.

This XIB is responsible for rendering top-side views which are not navigation bar right now. A navigation item is not something that is needed right now.

However, based on contextual navigation, there maybe a need for user to be able to go back to previous view, and a Back button is a requirement for such cases.

I would like to make this Back button part of this reusable XIB which forms top-side view inside every scene - but only conditionally, not everywhere.

I read documentation, and other questions on SO that tells me that UIBarButtonItem only exist in conjunction with a nav-controller.

I think this is an overkill for me, because:

1) I don't need back button everywhere

2) I don't need the look of nav-bar as top bar. My top bar is already designed in my XIB.

What should I change?

  • My XIB? If I can create outlets here for back button and make them hidden depending upon which view controller I am inside, it would be a highly welcome solution.
  • My XIB view .m file?
  • My view controller code where I want Back button?

An example with code will be highly appreciated.

Was it helpful?

Solution 2

Creating a base UIViewController wasn't much of an option because I just wanted this back button in couple of screens, there was no point in having an entire base class for it.

Finally, what I did was the inevitable: Embed first view controller inside a nav controller. Then have Push Segues from this first VC to all other VCs.

Since I did not want standard nav bar, I did the following:

[self.navigationcontroller setnavigationbarhidden:YES];

For back button, I added a custom UIButton to my own custom XIB view, and hid / showed it conditionally in a given view controller.

On the back button where it is being shown, I added a target that would perform the following:

[self.navigationController popViewControllerAnimated:YES];

OTHER TIPS

You can simply add button to the xib. And implement button action in the view controller class as follows:

- (IBAction) backButtonAction
{
    [self.navigationController popViewControllerAnimated:YES];
}

Create a common base view controller for all the viewcontrollers where you are going to add navigation bar. add your XIB in baseclass and create a function in base class to enable and disable the back button.

MyBaseClassVC.h

@interface MyBaseClassVC : UIViewController

@property (nonatomic, strong) UIView *titleBarView;

- (void) enableBackButtonInTitleBar;

//you can customize your back button with diff image and selector
- (void) enableBackButtonInTitleBarWithImageName:(NSString*)imageName andSelectorName:(NSString*)selectorName;

@end

MyBaseClassVC.m

......

/**
 * Enable the Left or Back Button
 */
- (void) enableBackButtonInTitleBar
{

UIImage *leftBarButtonImage = [UIImage imageNamed:@"Back_btn"];
UIButton *rightBarButton = [UIButton buttonWithType:UIButtonTypeCustom];
rightBarButton.bounds = CGRectMake( 0, 20, leftBarButtonImage.size.width, leftBarButtonImage.size.height);
[rightBarButton setImage:leftBarButtonImage forState:UIControlStateNormal];
[rightBarButton addTarget:self action:@selector(backToPreviousPage) forControlEvents:UIControlEventTouchUpInside];

[topbarview addsubview rightBarButton];
}

.....

in other viewcontroller subclass this viewcontroller.

For this kind of situation you need to think for the design of the app classes. I am giving you a very simple example that will make you think of an OOPs concept called as "Inheritance".

You can tweak the code to work with your header (i.e XIB)

I will create a base class btBaseViewController.h & btBaseViewController.m. This class will have the most common feature that I want all my viewcontrollers to have like

  1. A custom Header View with Button.
  2. A Content View.
  3. A method to renderUI.
  4. Another method to Enable / disable backButton.

In file btBaseViewController.h make it like this.

#import <UIKit/UIKit.h>

@interface btBaseViewController : UIViewController

@property(nonatomic, retain) btHeader *headerView;

-(void)showHeaderViewWithBackButton:(BOOL)backButton;

@end

In btBaseViewController.m implement the method as

-(void)showHeaderViewWithBackButton:(BOOL)backButton {
    // Now implement this method in a way to show the backbutton or not depending on 
    [headerView.backButton setAlpha:backButton];
}

Now Let us say you have btHomeViewController, derive it from btBaseViewController

#import "btBaseViewController.h"

@interface btHomeViewController : btBaseViewController

@end

In btHomeViewController.m in viewdidload write the code as

-(void)viewDidLoad {
    if(self.navigationController.viewControllers.count >=2 ) {
     // it means you have some thing on viewcontroller & you can go back
      [self showHeaderViewWithBackButton:YES];
    }
}

I have tried my best to project the solutions. You need to tweak it more.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top