より多くの情報が各iPhoneアプリに詰め込まれるにつれて、サイドスワイプメニューがより一般的なインターフェイス要素になっているようです。Facebookはそれを最新バージョンに含めており、新しいGmailアプリにも含まれているようです。このようなものを開発する最も効率的な方法は、より一般的なインターフェイス要素になりつつあるので、誰かが考えていたのではないかと思っていました。私はこれをどのように構築するかについて自分自身の考えを持っていますが、他の人々がどう思うか聞いてみたいです。
より多くの情報が各iPhoneアプリに詰め込まれるにつれて、サイドスワイプメニューがより一般的なインターフェイス要素になっているようです。Facebookはそれを最新バージョンに含めており、新しいGmailアプリにも含まれているようです。このようなものを開発する最も効率的な方法は、より一般的なインターフェイス要素になりつつあるので、誰かが考えていたのではないかと思っていました。私はこれをどのように構築するかについて自分自身の考えを持っていますが、他の人々がどう思うか聞いてみたいです。
回答:
私は最近これに遭遇しましたが、実際にコードを見たり、コントロールをテストしたりしていませんが、それは非常にまともな出発点であるように見えます。
編集:読者は他の回答も見てください:)
Tom Adriaenssenによるこのための素晴らしいライブラリがあります:Inferis / ViewDeck
使い方はとても簡単で、かなりのフォロワーがいます。
編集:
もう少し軽量なものについては、以下をチェックしてください。mutualmobile/ MMDrawerController
ViewDeckのすべての機能を備えているわけではありませんが、変更と拡張が簡単です。
このためのライブラリを作成しました。これはMFSideMenuと呼ばれます。
特に、iphone + ipad、portrait + landscape、左側または右側のメニュー、UITabBarController、およびパンジェスチャーのサポートが含まれます。
キーアイデアあなたがしなければならないことself.navigationController.viewのフレームまたはセンターを設定。処理する必要がある2つのイベントがあります。(1)barButtonItem press。(2)スワイプによるパンジェスチャー。
次のように、ビューコントローラをバックグラウンドに送信できます。
[self.view sendSubviewToBack:menuViewController.view];
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(buttonPressed:)];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self.navigationController.view addGestureRecognizer:panGestureRecognizer];
self.navigationItem.leftBarButtonItem = barButtonItem;
}
- (void)buttonPressed:(id)sender {
CGRect destination = self.navigationController.view.frame;
if (destination.origin.x > 0) {
destination.origin.x = 0;
} else {
destination.origin.x = 320;
}
[UIView animateWithDuration:0.25 animations:^{
self.navigationController.view.frame = destination;
}];
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
static CGPoint originalCenter;
if (recognizer.state == UIGestureRecognizerStateBegan)
{
originalCenter = recognizer.view.center;
} else if (recognizer.state == UIGestureRecognizerStateChanged)
{
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(originalCenter.x + translation.x, originalCenter.y);
}
else if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled || recognizer.state == UIGestureRecognizerStateFailed)
{
if (recognizer.view.frame.origin.x < 160) {
[UIView animateWithDuration:0.25 animations:^{
recognizer.view.center = CGPointMake(384, 487.5);
}];
} else {
[UIView animateWithDuration:0.25 animations:^{
recognizer.view.center = CGPointMake(384 + 320, 487.5);
}];
}
}
}
さらに良いのはJASidePanelsです。簡単に実装でき、iPhoneとiPadの両方で機能します。
Githubリンク:JASidePanels
Facebookの実装により、UIPanGestureRecognizerがUINavigationBarに配置されます。したがって、必要な場所でスワイプをキャッチできます。
これにより、x / zのタッチ方向を直接認識したり、発生した速度を認識したりすることができます。
また、UIViewをこのようにいじくり回す(明らかに異なるタスク->異なるコントローラーで一度に1つ以上画面に表示する)には、iOSの新しいViewController-Containment機能を使用する必要があります(私はそうしなければなりません)。Appleが意図していない方法でビュー階層をいじくり回すので、それなしのすべての実装は単に悪いです。
余談ですが、Facebookのできるだけ近くでそれを行う方法に本当に興味がある場合は、Github PKRevealControllerでソースを開いているプロジェクトをチェックしてください。
iOSアプリのFacebook / Pathスタイルのナビゲーションを実装するために開発者が作成した数十の異なるライブラリがあります。私はそれらすべてをリストできますが、あなたが最高のものを求めたように、ここに私がサイドスワイプナビゲーションメニューを実装するために使用する私の2つの選択肢があります:
1)ECSlidingViewController ストーリーボードの実装と使用も非常に簡単です。私はそれを実装する問題を抱えていないし、エラーやそのようなものを受け取っていません。私が提供したリンクには、それを使用するためのほとんどすべての説明があります。
2)SWRevealViewController このライブラリは簡単に使用でき、画像とすべての説明とともにそれを実装する方法を示すチュートリアルがここにあります。チュートリアルに従うだけで、後で感謝します。
ここを参照してください。非常に良い出発点です 。Facebookやパスなどのナビゲーションを引き出します
この質問は非常に人気がありますが、すべて簡単にインポートして使用できました...これが私が使用するものです... SWRevealController。
私は人々がそれを見逃していることに驚いています...それは本当に素晴らしいです!!! 使いやすいです。開発者には、さまざまなシナリオでの使用方法を確認できるいくつかのサンプルプロジェクトも含まれています。
SwiftとObjective-Cで独自のスライドアウトナビゲーションを開発するための優れたガイド。
Objective-C
迅速
GmailとFacebookはどちらもWebビューを多用しているため、ネイティブコードとレンダリングHTMLを区別するのは困難です。ただし、インターフェイスを見ると、表示したいコンテンツを含むUIViewの下に、画面幅(320pt)よりも狭い幅のUITableViewが配置されているようです。異なるテーブルビュー行を選択すると、おそらくコンテンツビューのサブビューがスワップアウトされます。
少なくとも、それが私が問題に取り組む方法です。それがどうあるべきかを指示するのは難しいです。すぐにジャンプして実験を開始してください!
github GSSlideMenuでこのリポジトリ を作成したい場合は、Facebookスタイルのメニューを作成できます。
これはまさにFacebookサイドバーのクローンです: GHSidebarNavライブラリ
とても使いやすい。指導は
右側のビューは、UIScrollViewのサブクラス内にある可能性があります。このサブクラスでは- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
、ユーザーがサブビューに触れた場合にのみ、オーバーライドしてYESを返すことができます。このようにして、透明なUIScrollViewを他のビューの上に配置し、サブビューの外で発生するタッチイベントを通過させることができます。そして、あなたは無料でスクロールのものを手に入れます。
例えば:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
CGPoint location=[self convertPoint:point toView:subview];
return (location.x > 0 &&
location.x < subview.frame.size.width &&
location.y > 0 &&
location.y < subview.frame.size.height);
}
または:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
return [subview pointInside:
[self convertPoint:point toView:subview] withEvent:event];
メインビューの下に(スワイプして表示される)メニューを追加してみてください。ビューのタッチイベントのサブスクライブを開始します。
を実装しtouchesMoved:
、最初gesture
が垂直(必要に応じてメインビューをスクロールする)か、水平(ここではメニューを表示する)かを確認します。水平の場合は- (void)scrollAwayMainView:(NSUInteger)pixels
、別のメソッドの呼び出しを開始します。呼び出されるたびtouchesMoved:
に、メインビューの開始点からのピクセル数を計算し、その数をメソッドに渡します。そのメソッドの実装で、次のコードを実行します。
[mainView scrollRectToVisible:CGRectMake:(pixels,
mainView.origin.y,
mainView.size.width,
mainView.size.height];
この質問に対する私の解決策をチェックしてください:
サードパーティのライブラリなしでカスタムスライドメニューを作成する方法。
サブクラス化してコンテンツを入力するだけでよい単一のクラス。
こちらがクラスです。詳細については、上記のリンクを参照してください。
#import <UIKit/UIKit.h>
@interface IS_SlideMenu_View : UIView <UIGestureRecognizerDelegate>
{
UIView* transparentBgView;
BOOL hidden;
int lastOrientation;
}
@property (strong, nonatomic) UIView *menuContainerV;
+ (id)sharedInstance;
- (BOOL)isShown;
- (void)hideSlideMenu;
- (void)showSlideMenu;
@end
#import "IS_SlideMenu_View.h"
@implementation IS_SlideMenu_View
+ (id)sharedInstance
{
static id _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[[self class] alloc] init];
});
return _sharedInstance;
}
- (instancetype)initWithFrame:(CGRect)frame
{
frame = [[[UIApplication sharedApplication] delegate] window].frame;
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
transparentBgView = [[UIView alloc] initWithFrame:frame];
[transparentBgView setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.6]];
[transparentBgView setAlpha:0];
transparentBgView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureRecognized:)];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gestureRecognized:)];
[transparentBgView addGestureRecognizer:tap];
[transparentBgView addGestureRecognizer:pan];
[self addSubview:transparentBgView];
frame.size.width = 280;
self.menuContainerV = [[UIView alloc] initWithFrame:frame];
CALayer *l = self.menuContainerV.layer;
l.shadowColor = [UIColor blackColor].CGColor;
l.shadowOffset = CGSizeMake(10, 0);
l.shadowOpacity = 1;
l.masksToBounds = NO;
l.shadowRadius = 10;
self.menuContainerV.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[self addSubview: self.menuContainerV];
hidden = YES;
}
//----- SETUP DEVICE ORIENTATION CHANGE NOTIFICATION -----
UIDevice *device = [UIDevice currentDevice];
[device beginGeneratingDeviceOrientationNotifications];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:device];
lastOrientation = [[UIDevice currentDevice] orientation];
return self;
}
//********** ORIENTATION CHANGED **********
- (void)orientationChanged:(NSNotification *)note
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if(orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight){
NSLog(@"%ld",orientation);
if(!hidden && lastOrientation != orientation){
[self hideSlideMenu];
hidden = YES;
lastOrientation = orientation;
}
}
}
- (void)showSlideMenu {
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
self.frame = CGRectMake(0, 0, window.frame.size.width, window.frame.size.height);
[self.menuContainerV setTransform:CGAffineTransformMakeTranslation(-window.frame.size.width, 0)];
[window addSubview:self];
// [[UIApplication sharedApplication] setStatusBarHidden:YES];
[UIView animateWithDuration:0.5 animations:^{
[self.menuContainerV setTransform:CGAffineTransformIdentity];
[transparentBgView setAlpha:1];
} completion:^(BOOL finished) {
NSLog(@"Show complete!");
hidden = NO;
}];
}
- (void)gestureRecognized:(UIGestureRecognizer *)recognizer
{
if ([recognizer isKindOfClass:[UITapGestureRecognizer class]]) {
[self hideSlideMenu];
} else if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
static CGFloat startX;
if (recognizer.state == UIGestureRecognizerStateBegan) {
startX = [recognizer locationInView:self.window].x;
} else
if (recognizer.state == UIGestureRecognizerStateChanged) {
CGFloat touchLocX = [recognizer locationInView:self.window].x;
if (touchLocX < startX) {
[self.menuContainerV setTransform:CGAffineTransformMakeTranslation(touchLocX - startX, 0)];
}
} else
if (recognizer.state == UIGestureRecognizerStateEnded) {
[self hideSlideMenu];
}
}
}
- (void)hideSlideMenu
{
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
window.backgroundColor = [UIColor clearColor];
[UIView animateWithDuration:0.5 animations:^{
[self.menuContainerV setTransform:CGAffineTransformMakeTranslation(-self.window.frame.size.width, 0)];
[transparentBgView setAlpha:0];
} completion:^(BOOL finished) {
[self removeFromSuperview];
[self.menuContainerV setTransform:CGAffineTransformIdentity];
// [[UIApplication sharedApplication] setStatusBarHidden:NO];
hidden = YES;
NSLog(@"Hide complete!");
}];
}
- (BOOL)isShown
{
return !hidden;
}
@end