スライドナビゲーションパネルを作成する方法(2)


次に、スライドアウトナビゲーションパネルを作成する方法(1)

今右側に


MainViewControllerでmファイルで、次のimport文をファイルの上部に追加します.
   
   
   
   
  1. #import "RightPanelViewController.h"

次に、次の定数定義を追加します.
   
   
   
   
  1. #define RIGHT_PANEL_TAG 3

次に@interfaceに次のプロパティを追加すると、right viewとその現在のステータスが容易に取得されます.
   
   
   
   
  1. @property (nonatomic, strong) RightPanelViewController *rightPanelViewController;
  2. @property (nonatomic, assign) BOOL showingRightPanel;

次にgetRightViewメソッドを見つけ、既存のコードを削除し、次のコードを追加します.
   
   
   
   
  1. // init view if it doesn't already exist
  2. if (_rightPanelViewController == nil)
  3. {
  4. // this is where you define the view for the right panel
  5. self.rightPanelViewController = [[RightPanelViewController alloc] initWithNibName:@"RightPanelViewController" bundle:nil];
  6. self.rightPanelViewController.view.tag = RIGHT_PANEL_TAG;
  7. self.rightPanelViewController.delegate = _centerViewController;
  8.  
  9. [self.view addSubview:self.rightPanelViewController.view];
  10.  
  11. [self addChildViewController:self.rightPanelViewController];
  12. [_rightPanelViewController didMoveToParentViewController:self];
  13.  
  14. _rightPanelViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
  15. }
  16.  
  17. self.showingRightPanel = YES;
  18.  
  19. // set up view shadows
  20. [self showCenterViewWithShadow:YES withOffset:2];
  21.  
  22. UIView *view = self.rightPanelViewController.view;
  23. return view;

上のコードはgetLeftViewをコピーしたものですが、クラスと属性が異なるだけです.上のコードに何か疑問があれば、前の説明を振り返ってみてください.
以前と同様に、xibファイルに関連するIBActionとIBOutletが接続されています.次はCenterViewControllerです.xibファイルの断面図で、puppiesボタンの接続関係が表示されます.
上図に示すように、kittiesボタンと同様に、puppiesボタンが接続されているIBOutletはrightButton、IBActionはbtnMovePanelLeft:.このボタンはcenter panelのスライドを制御して右側のpanelを表示します.
次にパネルを動かしましょう.
CenterControllerを開きます.mファイルをbtnMovePanelLeft:に次のコードを追加します.
   
   
   
   
  1. UIButton *button = sender;
  2. switch (button.tag) {
  3. case 0: {
  4. [_delegate movePanelToOriginalPosition];
  5. break;
  6. }
  7.  
  8. case 1: {
  9. [_delegate movePanelLeft];
  10. break;
  11. }
  12.  
  13. default:
  14. break;
  15. }

同様に,上記のコードはbtnMovePanelRight:メソッドの実装と何の違いもない.delegateの呼び出し方法はほとんど同じであることがわかります.
以前にmovePanelToOriginalPostionメソッドが実装されていたため、残りのタスクはmovePanelLeftメソッドを追加し、resetMainViewを修正してright panelを処理するだけでよい.
 

右側を表示


MainViewControllerを開きます.mファイルをmovePanelLeft:メソッドに次のコードを追加します.
   
   
   
   
  1. UIView *childView = [self getRightView];
  2. [self.view sendSubviewToBack:childView];
  3.  
  4. [UIView animateWithDuration:SLIDE_TIMING delay:0 options:UIViewAnimationOptionBeginFromCurrentState
  5. animations:^{
  6. _centerViewController.view.frame = CGRectMake(-self.view.frame.size.width + PANEL_WIDTH, 0, self.view.frame.size.width, self.view.frame.size.height);
  7. }
  8. completion:^(BOOL finished) {
  9. if (finished) {
  10.  
  11. _centerViewController.rightButton.tag = 0;
  12. }
  13. }];

上のコードはmovePanelRightメソッドの基本と同じで、ここではあまり説明しません.
次にresetMainViewメソッドを見つけ、既存のコンテンツを次のコードで置き換えます.
   
   
   
   
  1. // remove left and right views, and reset variables, if needed
  2. if (_leftPanelViewController != nil)
  3. {
  4. [self.leftPanelViewController.view removeFromSuperview];
  5. self.leftPanelViewController = nil;
  6.  
  7. _centerViewController.leftButton.tag = 1;
  8. self.showingLeftPanel = NO;
  9. }
  10.  
  11. if (_rightPanelViewController != nil)
  12. {
  13. [self.rightPanelViewController.view removeFromSuperview];
  14. self.rightPanelViewController = nil;
  15.  
  16. _centerViewController.rightButton.tag = 1;
  17. self.showingRightPanel = NO;
  18. }
  19.  
  20. // remove view shadows
  21. [self showCenterViewWithShadow:NO withOffset:0];

上のコードで唯一変更されたのは、if文コードブロック:if(_rightPanelViewControl!=nil)を追加したことです.この文はright panel viewが存在するかどうかを判断します.これは前にleft panel viewをチェックしたのと同じです.そして、_right PanelView Controlは同じ処理をします!
プログラムをコンパイルして実行し、puppiesボタンをクリックすると、次の画面が表示されます.
よさそうですね.
次のセクションでは、ジェスチャー機能を追加する方法について説明します.

指を動かして


プログラムにジェスチャーを追加する処理は非常に簡単で、複雑すぎると思わないで、簡単に実現できます!
やはりMainViewControllerです.mファイルでsetupViewメソッドを見つけ、メソッドの末尾に次のコードを追加します.
   
   
   
   
  1. [self setupGestures];

次に、MainViewControllerをUIGestureRecognizerDelegateプロトコルに従う必要があります.UIGestureRecognizerDelegateをファイル上部の@interfaceに追加します.追加したコードは次のとおりです.
   
   
   
   
  1. @interface MainViewController ()<UIGestureRecognizerDelegate, CenterViewControllerDelegate>

最後にsetupGesturesメソッドを見つけ、次のコードブロックを追加します.
   
   
   
   
  1. UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(movePanel:)];
  2. [panRecognizer setMinimumNumberOfTouches:1];
  3. [panRecognizer setMaximumNumberOfTouches:1];
  4. [panRecognizer setDelegate:self];
  5.  
  6. [_centerViewController.view addGestureRecognizer:panRecognizer];

上記のコードは、UIpanGestureRecognizerを定義し、movePanel:メソッドを割り当て、ジェスチャーが検出されると呼び出されます.(後でmovePanel:メソッドを実装する必要があります.)
次に、panRecognizerを設定します.タッチの最大数と最小数を1に設定し、delegateも設定します.最後に、作成したばかりのpanRecognizerを_に追加します.centerViewController.viewで.
注意:UIGestureRecognizerクラスの詳細については、アップルの公式ドキュメントを参照してください.
次に、もう一つのことをするとジェスチャーでスライドできます.

今すぐビューを移動しましょう


ジェスチャーが認識されるとmovePanel:メソッドが呼び出されます.だから、本文の最後の任務はこの方法を実現することです.
movePanel:メソッドはshowPanelとpreVelocityの2つのプロパティに使用されます.MainViewControllerでmファイルの@interfaceにこの2つのプロパティを追加します.
   
   
   
   
  1. @property (nonatomic, assign) BOOL showPanel;
  2. @property (nonatomic, assign) CGPoint preVelocity;

movePanel:を見つけて、次のコードを追加します(たくさんありますよ!):
   
   
   
   
  1. [[[(UITapGestureRecognizer*)sender view] layer] removeAllAnimations];
  2.  
  3. CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
  4. CGPoint velocity = [(UIPanGestureRecognizer*)sender velocityInView:[sender view]];
  5.  
  6. if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
  7. UIView *childView = nil;
  8.  
  9. if(velocity.x &gt; 0) {
  10. if (!_showingRightPanel) {
  11. childView = [self getLeftView];
  12. }
  13. } else {
  14. if (!_showingLeftPanel) {
  15. childView = [self getRightView];
  16. }
  17.  
  18. }
  19. // Make sure the view you're working with is front and center.
  20. [self.view sendSubviewToBack:childView];
  21. [[sender view] bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
  22. }
  23.  
  24. if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
  25.  
  26. if(velocity.x &gt; 0) {
  27. // NSLog(@"gesture went right");
  28. } else {
  29. // NSLog(@"gesture went left");
  30. }
  31.  
  32. if (!_showPanel) {
  33. [self movePanelToOriginalPosition];
  34. } else {
  35. if (_showingLeftPanel) {
  36. [self movePanelRight];
  37. } else if (_showingRightPanel) {
  38. [self movePanelLeft];
  39. }
  40. }
  41. }
  42.  
  43. if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateChanged) {
  44. if(velocity.x &gt; 0) {
  45. // NSLog(@"gesture went right");
  46. } else {
  47. // NSLog(@"gesture went left");
  48. }
  49.  
  50. // Are you more than halfway? If so, show the panel when done dragging by setting this value to YES (1).
  51. _showPanel = abs([sender view].center.x - _centerViewController.view.frame.size.width/2) &gt; _centerViewController.view.frame.size.width/2;
  52.  
  53. // Allow dragging only in x-coordinates by only updating the x-coordinate with translation position.
  54. [sender view].center = CGPointMake([sender view].center.x + translatedPoint.x, [sender view].center.y);
  55. [(UIPanGestureRecognizer*)sender setTranslation:CGPointMake(0,0) inView:self.view];
  56.  
  57. // If you needed to check for a change in direction, you could use this code to do so.
  58. if(velocity.x*_preVelocity.x + velocity.y*_preVelocity.y &gt; 0) {
  59. // NSLog(@"same direction");
  60. } else {
  61. // NSLog(@"opposite direction");
  62. }
  63.  
  64. _preVelocity = velocity;
  65. }

上のコードの注視はすでに機能に対して良い解釈をした.以下に、理解すべき重要な情報を示します.
UIGestureRecognizerStateBegan,UIGestureRecognizerStateEnded,UIGestureRecognizerStateChangedの3つの状態を処理する必要があります.
translationInView:指定したviewの座標系にある位置のpointを返し、そのpointをtranslatedPoint変数に割り当てます.この変数はviewの位置を設定するために使用されます.
velocityInView:ジェスチャーの移動速度を1秒ごとに返します.この変数は方向の変化を決定するのに役立つ.
center,left,right viewを移動し,上記の3つの状態と組み合わせてジェスチャーの位置と速度/方向を決定することができる.
たとえば、ジェスチャーの方向が右の場合、left panelが表示されます.方向が左の場合、right panelが表示されます.コードと関連するコメントを表示することで、各ステータスに何が起こっているかがわかります.
プログラムを再コンパイルして実行します.センターパネルを左または右にスライドさせ、センターパネルの下にあるパネルを表示できるようになりました.
 

どこへ行くか


もしあなたが完全に本稿で紹介した方法に従って操作すれば、おめでとうございます.あなたはもうスライド式ナビゲーションパネルの忍者になりました.
本文があなたに役に立つことを望みます!ここでは、本明細書で説明した完全なサンプルエンジニアリング:completed project fileです.
DIYではなく定義済みのライブラリが好きなら、SWRevealViewControllerを見てください.ここの開発者の紹介を見ると、簡単に使えます.
本文の転載:http://beyondvincent.com/category/ios/raywenderlich/