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.
We can easily do it by ourselves. It's so easy.
The approach I explain here is being used in my app.
When a button is pressed in title bar a side bar has to slide in and out from left side.
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.