随着越来越多的信息填充到每个 iPhone 应用程序中,侧滑菜单似乎正在成为一个越来越常见的界面元素。Facebook 已经把它包含在他们的最新版本和 新的 Gmail 应用程序似乎也包含了这个功能中。我想知道是否有人对开发这样的东西的最有效的方法有什么想法,因为它正在成为一个更常见的接口元素。虽然我有自己的想法,如何建立这一点,我很好奇,听听其他人的想法。
Gmail 和 Facebook 都大量使用 web 视图,所以很难说什么是原生代码,什么是呈现的 HTML。然而,看看界面,他们似乎已经放置了一个宽度比屏幕宽度(320pt)更窄的 UITableView,在 UIView 下面包含他们想要显示的内容。选择不同的表视图行可能会取代内容视图的子视图。
至少,这是我解决问题的方法。很难决定它应该是什么样的。直接跳进去开始实验吧!
右边的视图可能位于 UIScrollView 的子类中。在这个子类中,只有当用户触摸子视图时,才能覆盖 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event以返回 YES。这样你就可以把透明的 UIScrollView 放在任何其他视图上,并且通过任何发生在子视图之外的触摸事件,你就可以免费得到滚动的东西。
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
例如:
- (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是垂直的(如果需要,滚动主视图)还是水平的(这里您想显示菜单)。如果它是水平的,那么每当调用 touchesMoved:时,就开始调用另一个方法 - (void)scrollAwayMainView:(NSUInteger)pixels,计算主视图应该在的起始点以外的像素数,并将这个数字传递给方法。在该方法实现中,运行以下代码:
touchesMoved:
gesture
- (void)scrollAwayMainView:(NSUInteger)pixels
[mainView scrollRectToVisible:CGRectMake:(pixels, mainView.origin.y, mainView.size.width, mainView.size.height];
Facebook 的实现在 UINavigationBar 上放置了一个 UIPanGestureIdentiizer,这样就可以在需要的地方抓取滑动信息。
这样就可以直接识别 x/z 中的触摸方向以及触摸速度。
同样,这种对 UIviews 的修补(在屏幕上同时使用不同的任务-> 因此不同的控制器)也应该(我想说必须)使用 iOS 新的 ViewController-遏制特性。没有这个功能的每个实现都很糟糕,因为它以苹果公司不希望的方式修补了视图层次结构。
旁注: 如果你真的很好奇如何尽可能接近 Facebook 的方式来完成它,请查看我在 Github PKRevealController上开源的项目。
我为此创建了一个库,名为 MFSideMenu。
除此之外,它还支持 iphone + ipad、肖像 + 风景、左右菜单、 UITabBarController 和平底锅手势。
如果你愿意,我在 github 上做了这个回购 它允许你创建一个 Facebook 风格的菜单,但是有一个“背面”的 webView (通常我发现的所有回购都有一个 tableView 作为“背面”视图)。
有一个伟大的图书馆为此汤姆 Adriaenssen: 地下室/视图层
它非常容易使用,并且拥有相当多的追随者。
编辑:
如果想了解更轻量级的内容,请查看: 互动/多媒体绘图机控制器
它不具备 ViewDeck 的所有特性,但是更容易修改和扩展。
另一种选择是使用 斯克林戈。它提供了一个类似于 youtube/facebook 应用程序的副菜单,以及所有你可以选择添加的菜单内置功能(例如聊天,邀请朋友等等)。.)
添加侧面菜单只需调用[ ScringoAgent startSession... ] ,所有配置都可以在站点上完成。
更好的是 JASidePanels,易于实现,可以在 iPhone 和 iPad 上运行。
Github 链接: JASidePanels
查看 MMDrawerController:
绘图控制器
我们找不到我们喜欢的图书馆,所以我们自己建了一个。
这里有一个很好的出发点: 滑出像 facebook 和 path 这样的导航栏
这个问题是相当流行,但它所有归结为容易导入和使用为我... 这里是我使用... SWRevealController。
我很惊讶人们会错过它... 它真的很棒! ! !而且容易使用。开发人员甚至还包括一些示例项目,让您了解如何在不同的场景中使用它。
你必须得到的 关键点子。你必须处理 两件事。(1) 按.(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); }]; } } }
这正是 Facebook 侧边栏的翻版: 导航库
非常容易使用
为了实现 iOS 应用程序的 Facebook/Path 风格导航,开发人员已经创建了数十个不同的库。我可以列出所有这些,但是正如你所要求的最好的一个,这里是我的两个选择,我用来实现侧滑导航菜单:
1) < a href = “ https://github.com/edgecase/ECSlidingViewController”rel = “ norefrer”> ECSlidingViewController 它非常容易实现和使用故事板也。我没有遇到任何实现它的问题,也没有收到任何错误或类似的东西。为了使用它,我提供的链接几乎有所有的解释。
2) < a href = “ https://github.com/John-Lluch/SWReveaViewController”rel = “ norefrer”> SWReveaViewController 这个库很容易使用,您可以找到一个教程 给你,它显示了如何实现它与所有的解释连同图像。你可以按照教程做,然后再谢我。
在 Swift 和 Objective-C 中开发自己的幻灯片导航的优秀指南。
目标 C
斯威夫特
看看我对这个问题的解答:
如何创建自定义幻灯片菜单没有第三方库。 ? ?
一个只需要子类化并用内容填充的类。
下面是这个类。有关详细信息,请参阅上面的链接。
#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