現在很多的APP中都有slide view,左右滑動出現側邊菜單欄的功能,Weico這個應用就有。
網上有很多第三方的類庫實現了這種效果,其實自己代碼寫的話也是很簡單的,下面我將介紹兩種方法實現slide view。---- 一種是用第三方類庫IIViewDeckController這個類庫實現的效果比起其他的都好,另一種是自己代碼實現這種效果,效果還ok。
實現方法一(使用第三方庫IIViewDeckController):
https://github.com/Inferis/ViewDeck?這個是類庫的下載地址,上面有介紹具體如何使用。不過大都不是用storyboard實現的,那么這里我介紹的是如何用storyboard實現。 ? (1 )方法①
首先注意要導入相關的頭文件,并且Link the?QuartzCore.framework
然后在storyboard中添加三個navigation視圖,分別表示中間,左邊和右邊的視圖,并且創建相應的controller。
我的處理是初始化一個IIViewDeckController 實例然后作為子視圖添加到最左邊的視圖中,而用右邊的三個navigation視圖 作為IIViewDeckController 實例對象的初始參數。
其中要注意的是,要分別在三個navigation視圖添加identifier,注意是添加到的是navigation controller對應的視圖(即第一個)。
下面看看代碼:
[cpp]?view plaincopyprint?
- (void)viewDidLoad?{?[super viewDidLoad];?// Do any additional setup after loading the view, typically from a nib.? UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];? CenterViewController *centerController = (CenterViewController *)[storyboard instantiateViewControllerWithIdentifier:@"CenterViewController"];? LeftViewController *leftController = (LeftViewController *)[storyboard instantiateViewControllerWithIdentifier:@"LeftViewController"];? RightViewController *rightController = (RightViewController *)[storyboard instantiateViewControllerWithIdentifier:@"RightViewController"];? self.containerController = [[IIViewDeckController alloc] initWithCenterViewController:centerController leftViewController:leftController rightViewController:rightController];? self.containerController.leftSize = 100;?self.containerController.rightSize = 200;? self.containerController.view.frame = self.view.bounds;?[self.view addSubview:self.containerController.view];? }?- (void)viewDidLoad{[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib. UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; CenterViewController *centerController = (CenterViewController *)[storyboard instantiateViewControllerWithIdentifier:@"CenterViewController"]; LeftViewController *leftController = (LeftViewController *)[storyboard instantiateViewControllerWithIdentifier:@"LeftViewController"]; RightViewController *rightController = (RightViewController *)[storyboard instantiateViewControllerWithIdentifier:@"RightViewController"]; self.containerController = [[IIViewDeckController alloc] initWithCenterViewController:centerController leftViewController:leftController rightViewController:rightController]; self.containerController.leftSize = 100;self.containerController.rightSize = 200; self.containerController.view.frame = self.view.bounds;?[self.view addSubview:self.containerController.view]; } 復制代碼 這里創建一個IIViewDeckController實例,然后把這個實例對象的視圖作為子視圖添加到這個view中,這樣就實現了跳轉到我們需要的IIViewDeckController那里了,讓我們創建的IIViewDeckController實例處理左右滑動出現側邊欄的任務了。?
(2 )方法②
這里再介紹一種實現方式:讓最左邊這個視圖繼承自IIViewDeckController然后在實現文件添加這個方法:
[cpp]?view plaincopyprint?
- (id)initWithCoder:(NSCoder *)aDecoder?{?self = [super initWithCoder:aDecoder];?UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];?self = [super initWithCenterViewController:[storyboard instantiateViewControllerWithIdentifier:@"CenterViewController"]?leftViewController:[storyboard instantiateViewControllerWithIdentifier:@"LeftViewController"]?rightViewController:[storyboard instantiateViewControllerWithIdentifier:@"RightViewController"]];?if (self) {?// Add any extra init code here?}?return self;?}?- (id)initWithCoder:(NSCoder *)aDecoder{self = [super initWithCoder:aDecoder];UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];self = [super initWithCenterViewController:[storyboard instantiateViewControllerWithIdentifier:@"CenterViewController"]leftViewController:[storyboard instantiateViewControllerWithIdentifier:@"LeftViewController"]rightViewController:[storyboard instantiateViewControllerWithIdentifier:@"RightViewController"]];if (self) {// Add any extra init code here}return self;} 復制代碼 實現的效果是: ? ? ? ?
實現方式二(不使用第三方庫):
下面簡單說說這種滑動出現側邊欄是怎么回事,明顯這就是一個視圖層疊,那么簡單點的話,就是往一個視圖里面添加幾個視圖,然后添加swipe手勢,左右滑動時,響應事件處理,在事件處理中讓最上面的視圖的位置發生變化,也就是視圖移動,這樣就可以顯示出下面的視圖,這樣大致就可以解決了。
這里同樣也是使用storyboard。而且storyboard里面的內容和上面的一樣(其實解決方式借鑒了上面的方法①)。
首先分別創建對應的中間,左邊,右邊視圖的controller(tableview controller)。
然后創建三個對應的屬性
[cpp]?view plaincopyprint?
@property(nonatomic, strong) MainViewController *centerController;?@property(nonatomic, strong) RightViewController *rightController;?@property(nonatomic, strong) LeftViewController *leftController;?@property(nonatomic, strong) MainViewController *centerController;@property(nonatomic, strong) RightViewController *rightController;@property(nonatomic, strong) LeftViewController *leftController; 復制代碼 接著作為subview添加到視圖中并添加swipe手勢。處理的代碼如下:?
[cpp]?view plaincopyprint? - (void)viewDidLoad? {?[super viewDidLoad];?// Do any additional setup after loading the view.? UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];? _centerController = (MainViewController *)[storyboard instantiateViewControllerWithIdentifier:@"MainViewController"];? _leftController = (LeftViewController *)[storyboard instantiateViewControllerWithIdentifier:@"LeftViewController"];? _rightController = (RightViewController *)[storyboard instantiateViewControllerWithIdentifier:@"RightViewController"];? [self.view addSubview:_centerController.view];?[_centerController.view setTag:1];?[_centerController.view setFrame:self.view.bounds];? [self.view addSubview:_leftController.view];?[_leftController.view setTag:2];?[_leftController.view setFrame:self.view.bounds];? [self.view addSubview:_rightController.view];?[_rightController.view setTag:3];?[_rightController.view setFrame:self.view.bounds];? [self.view bringSubviewToFront:_centerController.view];? //add swipe gesture?UISwipeGestureRecognizer *swipeGestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];?[swipeGestureRight setDirection:UISwipeGestureRecognizerDirectionRight];?[_centerController.view addGestureRecognizer:swipeGestureRight];? UISwipeGestureRecognizer *swipeGestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];?[swipeGestureLeft setDirection:UISwipeGestureRecognizerDirectionLeft];?[_centerController.view addGestureRecognizer:swipeGestureLeft];?}?-(void) swipeGesture:(UISwipeGestureRecognizer *)swipeGestureRecognizer {? CALayer *layer = [_centerController.view layer];?layer.shadowColor = [UIColor blackColor].CGColor;?layer.shadowOffset = CGSizeMake(1, 1);?layer.shadowOpacity = 1;?layer.shadowRadius = 20.0;?if (swipeGestureRecognizer.direction == UISwipeGestureRecognizerDirectionRight) {?[_leftController.view setHidden:NO];?[_rightController.view setHidden:YES];? [UIView beginAnimations:nil context:nil];?[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];?if (_centerController.view.frame.origin.x == self.view.frame.origin.x || _centerController.view.frame.origin.x == -100) {?[_centerController.view setFrame:CGRectMake(_centerController.view.frame.origin.x+100, _centerController.view.frame.origin.y, _centerController.view.frame.size.width, _centerController.view.frame.size.height)];?}? [UIView commitAnimations];?}?if (swipeGestureRecognizer.direction == UISwipeGestureRecognizerDirectionLeft) {?[_rightController.view setHidden:NO];?[_leftController.view setHidden:YES];? [UIView beginAnimations:nil context:nil];?[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];?if (_centerController.view.frame.origin.x == self.view.frame.origin.x || _centerController.view.frame.origin.x == 100) {?[_centerController.view setFrame:CGRectMake(_centerController.view.frame.origin.x-100, _centerController.view.frame.origin.y, _centerController.view.frame.size.width, _centerController.view.frame.size.height)];?}? [UIView commitAnimations];?}?}?- (void)viewDidLoad{[super viewDidLoad];// Do any additional setup after loading the view. UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; _centerController = (MainViewController *)[storyboard instantiateViewControllerWithIdentifier:@"MainViewController"]; _leftController = (LeftViewController *)[storyboard instantiateViewControllerWithIdentifier:@"LeftViewController"]; _rightController = (RightViewController *)[storyboard instantiateViewControllerWithIdentifier:@"RightViewController"];? [self.view addSubview:_centerController.view];[_centerController.view setTag:1];[_centerController.view setFrame:self.view.bounds]; [self.view addSubview:_leftController.view];[_leftController.view setTag:2];[_leftController.view setFrame:self.view.bounds]; [self.view addSubview:_rightController.view];[_rightController.view setTag:3];[_rightController.view setFrame:self.view.bounds]; [self.view bringSubviewToFront:_centerController.view]; //add swipe gestureUISwipeGestureRecognizer *swipeGestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];[swipeGestureRight setDirection:UISwipeGestureRecognizerDirectionRight];[_centerController.view addGestureRecognizer:swipeGestureRight]; UISwipeGestureRecognizer *swipeGestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];[swipeGestureLeft setDirection:UISwipeGestureRecognizerDirectionLeft];[_centerController.view addGestureRecognizer:swipeGestureLeft];}-(void) swipeGesture:(UISwipeGestureRecognizer *)swipeGestureRecognizer { CALayer *layer = [_centerController.view layer];layer.shadowColor = [UIColor blackColor].CGColor;layer.shadowOffset = CGSizeMake(1, 1);layer.shadowOpacity = 1;layer.shadowRadius = 20.0;if (swipeGestureRecognizer.direction == UISwipeGestureRecognizerDirectionRight) {[_leftController.view setHidden:NO];[_rightController.view setHidden:YES]; [UIView beginAnimations:nil context:nil];[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];if (_centerController.view.frame.origin.x == self.view.frame.origin.x || _centerController.view.frame.origin.x == -100) {[_centerController.view setFrame:CGRectMake(_centerController.view.frame.origin.x+100, _centerController.view.frame.origin.y, _centerController.view.frame.size.width, _centerController.view.frame.size.height)];} [UIView commitAnimations];}if (swipeGestureRecognizer.direction == UISwipeGestureRecognizerDirectionLeft) {[_rightController.view setHidden:NO];[_leftController.view setHidden:YES]; [UIView beginAnimations:nil context:nil];[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];if (_centerController.view.frame.origin.x == self.view.frame.origin.x || _centerController.view.frame.origin.x == 100) {[_centerController.view setFrame:CGRectMake(_centerController.view.frame.origin.x-100, _centerController.view.frame.origin.y, _centerController.view.frame.size.width, _centerController.view.frame.size.height)];} [UIView commitAnimations];}} 復制代碼 下面稍稍解說一下在swipe手勢的事件處理中的一些處理: ?①為center視圖添加陰影邊框
②這里swipe手勢響應的是左右滑動,右滑動時是要出現左視圖,所以要隱藏右視圖,同理就知道如何處理左滑動了。
③cente 視圖移動時添加了動畫
說明:我這樣處理大致還是可以實現這種效果的。下面附上一張在我應用在sina weibo demo中的效果圖:
還不錯吧!
下面進行一點點補充:上面我們實現的都是通過swipe滑動最上層的view來實現左右側移,那么這樣就太局限了,那么如何實現例如點擊下面view中的LEFT按鍵來移動上層的view呢?其實也很簡單,我這里的處理是用notification通知,就是在button那里發送一個通知,在上層的view監聽。當然呢,也可以用delegate和kvo實現,但是這個。。。暫時沒有研究,就算了,有空再了解一下。
下面附加一下代碼:
在下面那層view的controller添加這個方法:
[cpp]?view plaincopyprint?
- (IBAction)BackButton:(id)sender {?NSString *myString = @"back";?[[NSNotificationCenter defaultCenter] postNotificationName: @"back" object:myString userInfo: nil];?}?- (IBAction)BackButton:(id)sender {NSString *myString = @"back";[[NSNotificationCenter defaultCenter] postNotificationName: @"back" object:myString userInfo: nil];} 復制代碼 在上面這個層的view的controller添加下面的代碼:?
[cpp]?view plaincopyprint? [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(BackFunc:) name: @"back" object:nil];? id) BackFunc:(NSNotification*) notification {?NSString *get = [notification object];?if ([get isEqualToString:@"back"]) {? [UIView beginAnimations:nil context:nil];?[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];?[_centerController.view setFrame:CGRectMake(0, _centerController.view.frame.origin.y, _centerController.view.frame.size.width, _centerController.view.frame.size.height)];?[UIView commitAnimations];?}?[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(BackFunc:) name: @"back" object:nil]; -(void) BackFunc:(NSNotification*) notification {NSString *get = [notification object];if ([get isEqualToString:@"back"]) { [UIView beginAnimations:nil context:nil];[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];[_centerController.view setFrame:CGRectMake(0, _centerController.view.frame.origin.y, _centerController.view.frame.size.width, _centerController.view.frame.size.height)];[UIView commitAnimations];}} 復制代碼 這樣就ok啦啦!?
原文鏈接:http://blog.csdn.net/crayon_dys/article/details/9057637 |