現在很多的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對應的視圖(即第一個)。
下面看看代碼:
- (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然後在實現檔案添加這個方法:
- (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)。
然後建立三個對應的屬性
@property(nonatomic, strong) MainViewController *centerController;@property(nonatomic, strong) RightViewController *rightController;@property(nonatomic, strong) LeftViewController *leftController;
接著作為subview添加到視圖中並添加swipe手勢。處理的代碼如下:
- (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]; }}
下面稍稍解說一下在swipe手勢的事件處理中的一些處理:
①為center視圖添加陰影邊框
②這裡swipe手勢響應的是左右滑動,右滑動時是要出現左視圖,所以要隱藏右視圖,同理就知道如何處理左滑動了。
③cente 視圖移動時添加了動畫
說明:我這樣處理大致還是可以實現這種效果的。下面附上一張在我應用在sina weibo demo中的:
還不錯吧!
下面進行一點點補充:上面我們實現的都是通過swipe滑動最上層的view來實現左右側移,那麼這樣就太局限了,那麼如何?例如點擊下面view中的LEFT按鍵來移動上層的view呢?其實也很簡單,我這裡的處理是用notification通知,就是在button那裡發送一個通知,在上層的view監聽。當然呢,也可以用delegate和kvo實現,但是這個。。。暫時沒有研究,就算了,有空再瞭解一下。
下面附加一下代碼:
在下面那層view的controller添加這個方法:
- (IBAction)BackButton:(id)sender { NSString *myString = @"back"; [[NSNotificationCenter defaultCenter] postNotificationName: @"back" object:myString userInfo: nil];}
在上面這個層的view的controller添加下面的代碼:
[[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啦啦!