간단한 메뉴뷰를 하나 만드려는데, 전체적인 구조도 볼겸 관련 내용이 정리된 소스를 정리해본다.
참조 : 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 |