Instantly share code, notes, and snippets.
Created
October 9, 2012 08:46
-
Star
(1)
1
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save siqin/3857426 to your computer and use it in GitHub Desktop.
Path-Style Menu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.m | |
// PathStyleMenu | |
// | |
// Created by Jason Lee on 12-10-9. | |
// Copyright (c) 2012年 Jason Lee. All rights reserved. | |
// | |
#import "ViewController.h" | |
typedef enum _screenStateType { | |
kNormalState = 0, | |
kLeftState, // Show the left-view | |
kRightState, // Show the right-view | |
kDriftingState // Drifting | |
} ScreenStateType; | |
@interface ViewController () | |
@property (nonatomic, strong) UIView *leftView; | |
@property (nonatomic, strong) UIView *rightView; | |
@property (nonatomic, strong) UIView *middleView; | |
@property (nonatomic, strong) UIView *navBar; | |
@property (nonatomic, assign) BOOL isSliding; | |
@property (nonatomic, assign) ScreenStateType screenState; | |
@property (nonatomic, assign) BOOL canDrag; | |
@property (nonatomic, assign) CGFloat lastFingerX; | |
@end | |
@implementation ViewController | |
- (void)dealloc | |
{ | |
[super dealloc]; | |
// | |
[_leftView release]; | |
[_rightView release]; | |
[_middleView release]; | |
[_navBar release]; | |
} | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
// Do any additional setup after loading the view, typically from a nib. | |
// | |
_leftView = [[UIView alloc] initWithFrame:self.view.bounds]; | |
_leftView.backgroundColor = [UIColor greenColor]; | |
[self.view addSubview:self.leftView]; | |
// | |
_rightView = [[UIView alloc] initWithFrame:self.view.bounds]; | |
_rightView.backgroundColor = [UIColor yellowColor]; | |
[self.view addSubview:self.rightView]; | |
// | |
_middleView = [[UIView alloc] initWithFrame:self.view.bounds]; | |
_middleView.backgroundColor = [UIColor redColor]; | |
[self.view addSubview:self.middleView]; | |
[self setupNavBar]; | |
self.screenState = kNormalState; | |
} | |
- (void)viewDidUnload | |
{ | |
[super viewDidUnload]; | |
// | |
self.leftView = nil; | |
self.rightView = nil; | |
self.middleView = nil; | |
self.navBar = nil; | |
} | |
- (void)didReceiveMemoryWarning | |
{ | |
[super didReceiveMemoryWarning]; | |
// Dispose of any resources that can be recreated. | |
} | |
#pragma mark - Initialize UI | |
- (void)setupNavBar | |
{ | |
_navBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.middleView.frame.size.width, 44)]; | |
self.navBar.backgroundColor = [UIColor blueColor]; | |
[self.middleView addSubview:self.navBar]; | |
UIButton *leftNavBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; | |
leftNavBtn.frame = CGRectMake(10, 0, 44, 44); | |
[self.navBar addSubview:leftNavBtn]; | |
[leftNavBtn setTitle:@"Left" forState:UIControlStateNormal]; | |
[leftNavBtn addTarget:self action:@selector(leftNavBtnDidClick:) forControlEvents:UIControlEventTouchUpInside]; | |
UIButton *rightNavBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; | |
rightNavBtn.frame = CGRectMake(self.navBar.frame.size.width - 10 - 44, 0, 44, 44); | |
[self.navBar addSubview:rightNavBtn]; | |
[rightNavBtn setTitle:@"Right" forState:UIControlStateNormal]; | |
[rightNavBtn addTarget:self action:@selector(rightNavBtnDidClick:) forControlEvents:UIControlEventTouchUpInside]; | |
} | |
#pragma mark - Slide to Left or Right | |
#define LEFT_SLIDE_OFFSET 260.0f | |
#define RIGHT_SLIDE_OFFSET (-260.0f) | |
- (void)leftNavBtnDidClick:(UIButton *)btn | |
{ | |
if (kNormalState == self.screenState) { | |
[self slideFromeState:self.screenState toState:kLeftState]; | |
} else { | |
[self slideFromeState:self.screenState toState:kNormalState]; | |
} | |
} | |
- (void)rightNavBtnDidClick:(UIButton *)btn | |
{ | |
if (kNormalState == self.screenState) { | |
[self slideFromeState:self.screenState toState:kRightState]; | |
} else { | |
[self slideFromeState:self.screenState toState:kNormalState]; | |
} | |
} | |
- (void)slideFromeState:(ScreenStateType)oState toState:(ScreenStateType)dState | |
{ | |
if (self.isSliding) return ; | |
self.isSliding = YES; | |
__block CGRect rect = self.middleView.frame; | |
rect.origin.x = 0.0f; | |
id completionBlk = nil; | |
switch (oState) { | |
case kNormalState: | |
if (kLeftState == dState) { | |
self.rightView.hidden = YES; | |
rect.origin.x = LEFT_SLIDE_OFFSET; | |
} else if (kRightState == dState) { | |
self.leftView.hidden = YES; | |
rect.origin.x = RIGHT_SLIDE_OFFSET; | |
} | |
break; | |
case kLeftState: | |
case kRightState: | |
if (kNormalState == dState) { | |
completionBlk = ^(BOOL finished) { self.leftView.hidden = NO; self.rightView.hidden = NO; }; | |
} | |
break; | |
case kDriftingState: | |
if (kLeftState == dState) { | |
rect.origin.x = LEFT_SLIDE_OFFSET; | |
} else if (kRightState == dState) { | |
rect.origin.x = RIGHT_SLIDE_OFFSET; | |
} else if (kNormalState == dState) { | |
completionBlk = ^(BOOL finished) { self.leftView.hidden = NO; self.rightView.hidden = NO; }; | |
} | |
break; | |
default: | |
break; | |
} | |
id animationBlk = ^{ self.middleView.frame = rect; }; | |
[UIView animateWithDuration:0.3f animations:animationBlk completion:completionBlk]; | |
self.screenState = dState; | |
self.isSliding = NO; | |
} | |
#pragma mark - Finger Touch | |
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event | |
{ | |
UITouch *touch = [touches anyObject]; | |
CGPoint fingerPoint = [touch locationInView:self.middleView]; | |
if ([self.middleView pointInside:fingerPoint withEvent:nil]) { | |
fingerPoint = [touch locationInView:self.view]; | |
self.lastFingerX = fingerPoint.x; | |
} | |
} | |
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event | |
{ | |
UITouch *touch = [touches anyObject]; | |
CGPoint fingerPoint = [touch locationInView:self.view]; | |
// The user really wants to move the screen ? | |
if (!self.canDrag && abs(fingerPoint.x - self.lastFingerX) > 30) { | |
self.canDrag = YES ; | |
self.lastFingerX = fingerPoint.x; | |
} | |
if (!self.canDrag) return ; | |
CGRect rect = self.middleView.frame; | |
rect.origin.x += (fingerPoint.x - self.lastFingerX); | |
rect.origin.x = (rect.origin.x > LEFT_SLIDE_OFFSET) ? LEFT_SLIDE_OFFSET : rect.origin.x; | |
rect.origin.x = (rect.origin.x < RIGHT_SLIDE_OFFSET) ? RIGHT_SLIDE_OFFSET : rect.origin.x; | |
self.middleView.frame = rect; | |
if (rect.origin.x > 0) { | |
self.rightView.hidden = YES; | |
self.leftView.hidden = NO; | |
} else if (rect.origin.x < 0) { | |
self.leftView.hidden = YES; | |
self.rightView.hidden = NO; | |
} else { | |
self.leftView.hidden = self.rightView.hidden = NO; | |
} | |
self.lastFingerX = fingerPoint.x; | |
} | |
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event | |
{ | |
self.canDrag = NO; | |
CGFloat boundary = 50.0f; | |
CGRect rect = self.middleView.frame; | |
ScreenStateType lastScreenState = self.screenState; | |
self.screenState = kDriftingState; | |
switch (lastScreenState) { | |
case kNormalState: | |
if (rect.origin.x < (0 - boundary)) { | |
[self slideFromeState:self.screenState toState:kRightState]; | |
} else if (rect.origin.x > (0 + boundary)) { | |
[self slideFromeState:self.screenState toState:kLeftState]; | |
} else { | |
[self slideFromeState:self.screenState toState:kNormalState]; | |
} | |
break; | |
case kLeftState: | |
if (rect.origin.x < LEFT_SLIDE_OFFSET - boundary) { | |
[self slideFromeState:self.screenState toState:kNormalState]; | |
} else { | |
[self slideFromeState:self.screenState toState:kLeftState]; | |
} | |
break; | |
case kRightState: | |
if (rect.origin.x > RIGHT_SLIDE_OFFSET + boundary) { | |
[self slideFromeState:self.screenState toState:kNormalState]; | |
} else { | |
[self slideFromeState:self.screenState toState:kRightState]; | |
} | |
break; | |
default: | |
[self slideFromeState:self.screenState toState:kNormalState]; | |
break; | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment