Sidebar menu implementation on iOS like Facebook?

zeeshan shaikh picture zeeshan shaikh · Jun 10, 2013 · Viewed 33.1k times · Source

I want to create side-bar menu like in Facebook iPhone app in iOS 6.

How can I create it?

I'm new to this iPhone development.

Please give me some pointers or tell me some basic tutorial that I can follow step by step to achieve it.

Answer

Durai Amuthan.H picture Durai Amuthan.H · Jul 19, 2013

We can easily do it by ourselves. It's so easy.

The approach I explain here is being used in my app.

objective:

When a button is pressed in title bar a side bar has to slide in and out from left side.

Steps:

1) Create a view controller(home) and two nsObject classes(sidebar,main)

2) add a tool bar on view controller

3) In sidebar (Left side view):

i) Build a uiview(to be added on vc) with desired sidebar width within that add views as needed for your project

ii) then create button and make it as property because it's target events will have to occur in view controller

iii) you have to have two CGRects for both button and the resultant view one CGrect is for expanded state another CGrect is for collapsed

iv) as far as button is cocerned it's x is sidebarwidth-buttonwidth for expanded state and it's x is 0+buttonwidth for collapsed state and as far as view is concerned it's x is 0 for expanded state and it's x is -sidebarwidth for collapsed state

4) In main(right side view):

i) Build a UIView and add it to UiscollView(to be added on vc)

ii) UIView will have two CGREcts for UIscrollView one for expanded and one for collapsed

iii) UIview's x is 0 y is 0 width is 1024 and height is 726(landscape view height-toolbar width on vc)

iv) On Collapsed time uIscrollview's x is sidebarwidth y is 42(vc'tool bar height) and width is 1024-sidebarwidth and height is same as uiview's

v) on expanded time Uiscrollview's x is 0 and width becomes 1024

vi) Uiscrollview content size always should be 1024,726 as we need scrolling if the size is shrunk than this

5) In view controller (home page):

i) add both the side bar and main in home

ii) then add and event for the button in sidebar and then add it on the tool bar usign addsubview method

iii) In the button touch event call toggle events inside

 -(void)OnCollapsibleExtenderTouchUpInside
{
   [UIView animateWithDuration:1.0 animations:^{

    [sideBarObj ToggleVuPosition];

    [mainVuObj ToggleVuSize];

 }];

}

The below code works for me..(I just renamed some field for my own sake)

To understand the below code better:

1) The View controller name is Home and side bar name is side bar and right side area name is Main

2) I have wrote the coding for landscape alone...you can customize it for portrait also one use it.

Side bar:

#import <Foundation/Foundation.h>

@interface SideBar : NSObject
{
UIView *vuSideBar;

UIScrollView *scrollVuSideBar;

UIImageView *imgProfilePicture;

CGRect rectVuSideBar,rectExpandedScrollVuSideBar,rectCollapsedScrollVuSideBar,rectImgProfilePicture,rectExpandedBtnCollapsibleExtender,rectCollapsedBtnCollapsibleExtender;

 int sideBarWidth,sideBarHeight;
}

@property(strong,nonatomic)UIButton *btnCollapsibleExtender;

-(id)initWithParent:(UIView *)vuParent andToolBar:(UIToolbar *)toolBarParent;

-(void)ToggleVuPosition;

@end

Side bar implementation:

 #import "SideBar.h"

@interface  SideBar()

-(void)initRects;

-(void)initVus;

-(void)initOtherIvars;

-(void)AddViewsOnHierarchy;

-(void)AddToParentVu:(UIView *)ParentVu;

-(void)OnCollapsibleExtenderTouchUpInside;

@end

@implementation SideBar

@synthesize btnCollapsibleExtender;

-(id)initWithParent:(UIView *)vuParent andToolBar:(UIToolbar  *)toolBarParent
{
 self = [super init]; //calls init because UIResponder has no custom init methods
 if (self)
 {
    [self initOtherIvars];

    [self initRects];

    [self initVus];

    [self AddViewsOnHierarchy];

    [self AddToParentVu:vuParent];

    [self AddToParentToolbar:toolBarParent];

   }
   return self;
 }

 -(void)initOtherIvars
 {
   NSLog(@"initOtherIvars");

   sideBarWidth=300;

   sideBarHeight=768;
 }

 -(void)initRects
 {
  NSLog(@"initRects");

  rectExpandedScrollVuSideBar=CGRectMake(0,42,sideBarWidth,sideBarHeight);

 rectCollapsedScrollVuSideBar=CGRectMake(-sideBarWidth,42,sideBarWidth,sideBarHeight);

rectExpandedBtnCollapsibleExtender=CGRectMake(sideBarWidth-30,6,30,30);

rectCollapsedBtnCollapsibleExtender=CGRectMake(6,6,30,30);

rectVuSideBar=CGRectMake(0,0,sideBarWidth,sideBarHeight);

rectImgProfilePicture=CGRectMake(5,5,sideBarWidth-10,200);
 }

 -(void)initVus
 {
  NSLog(@"initVus");

   scrollVuSideBar=[[UIScrollView  alloc]initWithFrame:rectExpandedScrollVuSideBar];

   [scrollVuSideBar setContentSize:CGSizeMake(sideBarWidth,sideBarHeight)];


   btnCollapsibleExtender=[[UIButton alloc]initWithFrame:rectExpandedBtnCollapsibleExtender];

   UIImage *imgCollapsibleExtender=[UIImage imageNamed:@"SideBarExpandCollapse.png"];

   [btnCollapsibleExtender setImage:imgCollapsibleExtender forState:UIControlStateNormal];


   vuSideBar=[[UIView alloc]initWithFrame:rectVuSideBar];

   [vuSideBar setBackgroundColor:[UIColor darkGrayColor]];


   imgProfilePicture=[[UIImageView alloc]initWithFrame:rectImgProfilePicture];

   UIImage *imgDefaultProfile=[UIImage imageNamed:@"defaultProfileImage.png"];

   [imgProfilePicture setImage:imgDefaultProfile];

  }

 -(void)AddViewsOnHierarchy
{
   NSLog(@"AddViewsOnHierarchy");

   [vuSideBar addSubview:imgProfilePicture];

   [scrollVuSideBar addSubview:vuSideBar];
 }

 -(void)AddToParentVu:(UIView *)ParentVu
 {
   NSLog(@"AddToParent vu");

  [ParentVu addSubview:scrollVuSideBar];
 }

 -(void)AddToParentToolbar:(UIToolbar *)ParentToolBar
 {
  NSLog(@"AddToParent toolbar");

 [ParentToolBar addSubview:btnCollapsibleExtender];
 }

 -(void)ToggleVuPosition
 {
 switch ((int)scrollVuSideBar.frame.origin.x)
 {
     case 0:

        scrollVuSideBar.frame=rectCollapsedScrollVuSideBar;

             btnCollapsibleExtender.frame=rectCollapsedBtnCollapsibleExtender;

        break;

      default:

        scrollVuSideBar.frame=rectExpandedScrollVuSideBar;

          btnCollapsibleExtender.frame=rectExpandedBtnCollapsibleExtender;

        break;
   }
 }

@end

Main(Right side view):

 #import <Foundation/Foundation.h>

 @interface MainView : NSObject
 {
  UIView *vuMain;

  UIScrollView *scrollVuMain;

  CGRect  rectVuMain,rectScrollVuMainExpanded,rectScrollVuMainCollpased;

  int mainWidth,mainHeight,sideBarWidth,HeaderBarHeight;
 }

 -(id)initWithParent:(UIView *)vuParent;

 -(void)ToggleVuSize;
 @end

Main(Right side view) implementation:

#import "MainView.h"

@interface MainView ()

-(void)initRects;

-(void)initVus;

-(void)initOtherIvars;

-(void)AddViewsOnHierarchy;

-(void)AddToParentVu:(UIView *)ParentVu;

@end

@implementation SGGI_MainView

-(id)initWithParent:(UIView *)vuParent
{
  self = [super init]; //calls init because UIResponder has no custom init methods
  if (self)
  {
    [self initOtherIvars];

    [self initRects];

    [self initVus];

    [self AddViewsOnHierarchy];

    [self AddToParentVu:vuParent];
   }
   return self;
 } 

-(void)initRects
{
rectVuMain=CGRectMake(0,0,1024,726);

       rectScrollVuMainExpanded=CGRectMake(0,HeaderBarHeight,mainWidth,mainHeight-HeaderBarHeight);

  rectScrollVuMainCollpased=CGRectMake(sideBarWidth,HeaderBarHeight,mainWidth-sideBarWidth,mainHeight-HeaderBarHeight);
}

-(void)initVus
{
 scrollVuMain=[[UIScrollView alloc]initWithFrame:rectScrollVuMainCollpased];

 [scrollVuMain setContentSize:CGSizeMake(mainWidth,mainHeight-HeaderBarHeight)];

 vuMain=[[UIView alloc]initWithFrame:rectVuMain];

 UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(0,0,1024,30)];

 [lbl setText:@"Details123456789abcdefghijklmnopqrstuvwxyz987654321abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz9876"];

 [vuMain addSubview:lbl];


}

-(void)initOtherIvars
{
 NSLog(@"initOtherIvars");

 mainWidth=1024;

 mainHeight=768;

 sideBarWidth=300;

 HeaderBarHeight=42;

}

-(void)AddViewsOnHierarchy
{
 [scrollVuMain addSubview:vuMain];
}

  -(void)AddToParentVu:(UIView *)ParentVu
 {
   [ParentVu addSubview:scrollVuMain];
 }

  -(void)ToggleVuSize
 {

 switch ((int)scrollVuMain.frame.size.width)
 {
    case 1024:

        scrollVuMain.frame=rectScrollVuMainCollpased;

        break;

    default:

        scrollVuMain.frame=rectScrollVuMainExpanded;

        break;
  }
}

@end

Home(Embedding the above two one a VC):

#import <UIKit/UIKit.h>

@interface Home : UIViewController

@end

Home implementation:

#import "Home.h"

#import "sideBar.h"

#import "Main.h"

@interface Home ()
{
 sideBar *sideBarObj;

 Main *mainVuObj;

 UIToolbar *HeaderBarObj;
 }

 -(void)AddSideBar;

 -(void)AddMainView;

 -(void)AddHeaderBar;

 -(void)AddCollapsibleExtenderEvent;

 -(void)OnCollapsibleExtenderTouchUpInside;

@end

@implementation Home

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
 if (self) {
    // Custom initialization
 }
  return self;
}

- (void)viewDidLoad
{
 [super viewDidLoad];

 [self.view setBackgroundColor:[UIColor grayColor]];

 [self AddHeaderBar];

 [self AddSideBar];

  [self AddMainView];

 [self AddCollapsibleExtenderEvent];
}

  - (void)didReceiveMemoryWarning
 {
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
 }

-(void)AddHeaderBar
 {
  HeaderBarObj=[[UIToolbar  alloc]initWithFrame:CGRectMake(0,0,1024,42)];

  [self.view addSubview:HeaderBarObj];
 }

-(void)AddSideBar
{
 sideBarObj=[[SideBar alloc]initWithParent:self.view andToolBar:HeaderBarObj];
}

-(void)AddMainView
{
 mainVuObj=[[MainView alloc]initWithParent:self.view];
}

-(void)AddCollapsibleExtenderEvent
{
SEL   selCollapsibleTouch=@selector(OnCollapsibleExtenderTouchUpInside);

 [sideBarObj.btnCollapsibleExtender addTarget:self action:selCollapsibleTouch forControlEvents:UIControlEventTouchUpInside];
}

-(void)OnCollapsibleExtenderTouchUpInside
{
     [UIView animateWithDuration:1.0 animations:^{

    [sideBarObj ToggleVuPosition];

    [mainVuObj ToggleVuSize];

 }];

}

@end

The above code can be customized further by without using main and adding the code for that in Home view controller likewise one can avoid a separate class for sidebar and include that in home viewcontroller itself.

As far as when user presses button in sidebar, for changes in main view you can use protocol delegates or we can have the buttons in sidebar as property and add events in view controller.

I hope this helps.