如何在没有第三方库的情况下创建自定义幻灯片菜单。?
Posted
技术标签:
【中文标题】如何在没有第三方库的情况下创建自定义幻灯片菜单。?【英文标题】:How to create custom slide menu without third party library.? 【发布时间】:2016-05-05 07:44:45 【问题描述】:我想在我的 ios 应用程序中实现滑动菜单,例如抽屉 (Andriod)。我经历了一个教程,但他们都在使用第三方库。是否有可能创建自定义幻灯片菜单。我尝试使用以下代码创建它,但它仅适用于 xib 文件:
- (IBAction)sidemenu:(id)sender
[UIView animateWithDuration:0.50f animations:^
view.frame = self.view.frame;
completion:^(BOOL finished)
swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipGestureLeftAction:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeLeft];
];
- (void)SwipGestureAction
UISwipeGestureRecognizer *swiperight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipGestureRightAction:)];
swiperight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swiperight];
#pragma mark AddSwipeGestureLeftAndRight
- (void)SwipGestureRightAction:(UISwipeGestureRecognizer *)swipeRight
[UIView animateWithDuration:0.50f animations:^
view.frame = self.view.frame;
completion:^(BOOL finished)
swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipGestureLeftAction:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeLeft];
];
- (void)SwipGestureLeftAction:(UISwipeGestureRecognizer *)swipeRight
[UIView animateWithDuration:0.50f animations:^
[view setFrame:CGRectMake(self.view.frame.origin.x - self.view.frame.size.width, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height)];
completion:^(BOOL finished)
[self.view removeGestureRecognizer:swipeLeft];
];
【问题讨论】:
看到这个兄弟,它可以帮助你***.com/questions/7989020/… 好的先生,让我看看这个 先生,如果我点击该链接,它将在左侧推送视图,但我想要的是视图应该出现在当前视图中。它不应该被推动。像 android 中的抽屉一样? @Bhavinn 谢谢先生,这是一个很好的教程,但我现在正在研究目标 c? @Anbu.Karthik 先生,这个任务我应该遵循什么教程吗? 【参考方案1】:这是我为你准备的:
我为所有项目中的所有幻灯片菜单创建了一个超级类。它管理幻灯片菜单的显示和隐藏,并处理方向更改。它从当前视图顶部的左侧滑入,并用深色透明背景部分遮盖了视图的其余部分。 如果您需要其他行为(例如推出当前视图),只需覆盖动画部分。 我的幻灯片菜单是单例的,因为在我们的应用程序中,我们只在每个屏幕上使用一个幻灯片菜单。
#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
子类只需要在menuContainerV
视图中添加子视图,并进行管理即可。
一个例子:
我创建了一个子类,其中包含一个标题视图和一个表格视图作为其内容。我在 xib 中创建了内容视图,而 xib 的所有者就是这个子类。这样我就可以将 outlet 绑定到 xib。
#import "IS_SlideMenu_View.h"
@interface CC_SlideMenu_View : IS_SlideMenu_View<UITableViewDelegate, UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UIView *headerView;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
...
@end
当幻灯片菜单被实例化时,我加载 xib 并将内容视图添加到 menuContainerV 视图。
#import "CC_SlideMenu_View.h"
@implementation CC_SlideMenu_View
- (instancetype)init
self = [super init];
if (self)
UIView *v = [[[NSBundle mainBundle] loadNibNamed:@"CC_SlideMenu_View" owner:self options:nil] firstObject];
v.frame = self.menuContainerV.bounds;
[self.menuContainerV addSubview:v];
self.tableView.backgroundColor = [UIColor darkGrayColor];
return self;
...
@end
结果类似于this。
【讨论】:
感谢您的回答先生,我尝试实现它 先生,您的项目中使用的是xib吗?因为代码好像是按照xib写的? 您可以将 xibs 用于单独的视图或视图控制器,并将同一时间情节提要用于其他视图控制器。 Xib 和故事板并不相互排斥。这是你的意思吗? 是的,先生,谢谢,我不敢一起使用。现在很好以上是关于如何在没有第三方库的情况下创建自定义幻灯片菜单。?的主要内容,如果未能解决你的问题,请参考以下文章
iOS - 如何在没有第三方框架的情况下在 Swift 中创建自定义动画横幅
Flutter 如何在没有任何第三方库的情况下从 url 下载文件
如何在不需要自定义库的情况下在 Google Colabs 上使用 Selenium IDE,例如科拉?