본문 바로가기

프로그래밍/iOS,macOS

슬라이드메뉴

간단한 메뉴뷰를 하나 만드려는데, 전체적인 구조도 볼겸 관련 내용이 정리된 소스를 정리해본다.

참조 : https://www.raywenderlich.com/32054/how-to-create-a-slide-out-navigation-like-facebook-and-path


* 단순히 사용되는 메쏘드나 구조를 살펴보기 위함이라 실제 내용과 차이가 있음.

이 튜토리얼은 메뉴뷰가 에니메이션되는 형태가 아닌 센터뷰가 이동하는 형태로 처리되어 있다. 따라서, 메뉴뷰는 고정되어 있고, 센터뷰가 슬라이드되면서 메뉴뷰가 보이게 된다.


메뉴뷰가 이동하게하려면 frame 등 영역정보를 화면 외부로 설정해서 안으로 에니메이션 하면 될것으로 보인다.




센터뷰 생성

self.centerViewController = [[centerViewController alloc] initWithNibName:@"CenterViewController" bundle:nil];




센터뷰를 메인뷰에 포함시킨다

[self addChildViewController:_centerViewController];

[self.view addSubView:self.centerViewController.view];

[_centerViewController didMoveToParentViewController:self];



*별도의 드래그나 제스추어가 필요없어서 바로 메뉴뷰를 생성하는 루틴으로 넘어가는데, 드래그를 처리하기 위해서는 이부분에 제스추어 설정이 들어가야 한다.



메뉴뷰를 생성

메뉴열기 버튼이 눌리거나 오른쪽 드래그가 시작될때 메뉴부를 얻어온다.


if( _menuViewController == nil ) {

self.menuViewController= [[MenuVewController alloc] 

initWithNibName:@"MenuViewController"

bundle:nil];

[self addChildViewController:_menuViewController];

[self.view addSubview:self.menuViewController.view];

[_menuViewController didMoveToParentViewController:self];

_menuViewController.view.frame = CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height);

}


[self showCenterViewWithShadow:YES withOffset:-2];




버튼 누르면 메뉴뷰를 보인다


#define SLIDE_TIMING .25

#define PANEL_WIDTH 60


[UIView  animateWithDuration:SLIDE_TIMING                    

delay:0 

options:UIViewAnimationOptionBeginFromCurrentState 

animations:^{

_centerViewController.view.frame = CGRectMake(

-self.view.frame.size.width + PANEL_WIDTH,

0,

self.view.frame.size.width,

self.view.frame.size.height);

}

completion:^{


}];




메뉴뷰 닫기

[UIView animateWithDuration:SLIDE_TIMING

delay:0

options:UIViewAnimationOptionBeginFromCurrentState

animations:^{

_centerViewController.view.frame = CGRectMake(

0,

0,

self.view.frame.size.width,

self.view.frame.size.height);

}

completion:^{


// 초기화

if( _menuViewController != nil ) {

[self.menuViewController.view removeFromSuperview];

self.menuViewController= nil;


}


[self showCenterViewWithShadow:NO withOffset:0];

}];




그림자처리


#define CORNER_RADIUS 4


-(void)showCenterViewWithShadow:(BOOL)vlaue withOffset:(double)offset {

if(value) {

[_centerViewController.view.layer setCornerRadius:CORNER_RADIUS];

[_centerViewController.view.layer setShadowColor:[UIColor blackColor].CGColor];

[_centerViewController.view.layer setShadowOpacity:0.8];

[_centerViewController.view.layer setShadowOffset:CGSizeMake(offset, offset);

} else {

[_centerViewController.view.layer setCornerRadius:0.0f];

[_centerViewController.view.layer setShadowOffset:CGSizeMake(offset, offset);

}

}



뷰의 순서변경

메뉴뷰가 항상 존재해야 하는 경우?





제스추어설정(드래그) 

해당 튜토리얼과 소스에는 드래그 처리 관련 내용이 있어 이 부분도 그냥 정리



UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] 

initWithTarget:self

action:@selector(movePanel:)];

[panRecognizer setMinimumNumberOfTouches:1];

[panRecognizer setMaximumNumberOfTouches:1];

[panRecognizer setDelegate:self];

[_centerViewController.view addGestureRecognizer:panRecognizer];



delegate는 UIGestureRecognizerDelegate 인데, 모두 optional이다.




드래그 셀렉터

오른쪽으로 드래그된 경우 왼쪽뷰를 가져온다.

BOOL showPanel; // 메뉴뷰가 보여지고 있는경우 YES로 설정된다.



-(void)movePanel:(id)sender{

[[[sender view] layer] removeAllAnimations];


CGPoint translatedPoint = [sender translationInView:self.view];

CGPoing velocity = [sender velocityInView:[sender view]];



// 드래그시작

if([sender state] == UIGestureRecognizerStateBegan) {

UIView *childView = nil;

if(velocity.x > 0 ) {

childView = 메뉴뷰를 생성한다.

}


// 메뉴뷰를 뒤로 보냄.

[self.view sendSubviewToBack:childView];


// 센터뷰를 앞으로 보임.(뭔가 조금 이상???  자기가 자기를 앞으로???)

[[sender view] bringSubviewToFront:[sender view]];

}


// 드래그 종료

if([sender state] == UIGestureRecognizerStateEnded) {

if( !_showPanel ) {

메뉴뷰 닫기

} else {

메뉴뷰 열기


}

}



// 드래그 중...

if( [sender state] == UIGestureRecognizerStateChanged ) {

_showPanel = abs( [sender view].center.x - _centerViewController.view.frame.size.width/2) >                                             _centerViewController.view.frame.size.width/2;


[sender view].center = CGPointMake([sender view].center.x + translatedPoint.x, [sender view].center.y);

[sender setTranslation:CGPintMake(0,0) inView:self.view];



// 방향에 따라 처리할 내용

if( velocity.x*_preVelocity.x + velocity.y*_preVelocity.y > 0 ) {

// 동일한 방향

} else {

// 반대방향

}


_preVelocity = velocity;

}

}



'프로그래밍 > iOS,macOS' 카테고리의 다른 글

오토레이아웃 이것저것 / Constraint / UITextView  (0) 2016.10.25
커스텀객체와 인터페이스빌더  (0) 2016.10.23
스토리보드 / XIB  (0) 2016.10.22
싱글톤  (0) 2016.10.19
코어 데이터 정리  (0) 2016.10.18
UITableView / UICollectionView  (0) 2016.10.16
파일 가져오기  (0) 2016.10.16
뷰 에니메이션  (0) 2016.10.13
비동기 처리 ( GCD , NSOperation )  (0) 2016.10.13
[objective-c] 블록구문  (0) 2016.10.13