android 仿ios侧滑菜单,iOS仿QQ侧滑菜单

本文介绍了如何在iOS应用中实现类似QQ的侧滑菜单效果。通过自定义`DBHWindow`类,实现了显示和隐藏左侧视图的动画,并在主控制器`DBHRootViewController`中添加了拖动手势,使得用户可以左右滑动来展示和隐藏菜单。菜单内容为一个简单的`UITableView`,但可以按需替换为其他视图。文中提供了详细的代码实现步骤和示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近看到QQ上的侧滑菜单特有意思,就自己试着去实现了一下,看上去效果相差不大。

最后的效果图:

d61b57a23ce3

首先,需要自定义一个window

DBHWindow.h:

#import

@interface DBHWindow : UIWindow

/**

显示左侧视图动画

*/

- (void)showLeftViewAnimation;

/**

隐藏左侧视图动画

*/

- (void)hiddenLeftViewAnimation;

/**

显示左侧视图动画

@param excursion 偏移宽度

*/

- (void)showLeftViewAnimationWithExcursion:(CGFloat)excursion;

@end

DBHWindow.m:

#import "DBHWindow.h"

#import "DBHRootViewController.h"

static NSString * const kDBHTableViewCellIdentifier = @"kDBHTableViewCellIdentifier";

@interface DBHWindow ()

@property (nonatomic, strong) UITableView *tableView;

@property (nonatomic, strong) UIView *shadeView;

@end

@implementation DBHWindow

#pragma mark - Lifecycle

- (instancetype)initWithFrame:(CGRect)frame

{

self = [super initWithFrame:frame];

if (self) {

[self setUI];

}

return self;

}

#pragma mark - UI

- (void)setUI {

[self addSubview:self.tableView];

}

#pragma mark - UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return 5;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDBHTableViewCellIdentifier forIndexPath:indexPath];

cell.textLabel.text = [NSString stringWithFormat:@"第%ld行", indexPath.row];

cell.selectionStyle = UITableViewCellSelectionStyleNone;

return cell;

}

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

[self hiddenLeftViewAnimation];

DBHRootViewController *rootVC = (DBHRootViewController *)self.rootViewController.childViewControllers.firstObject;

rootVC.selectedIndex = indexPath.row;

}

#pragma mark - Event Responds

/**

点击了右侧半透明区域

*/

- (void)respondsToShadeView {

[self hiddenLeftViewAnimation];

}

/**

右侧半透明区域的左滑手势

*/

- (void)respondsToPanGR:(UIPanGestureRecognizer *)panGR {

CGPoint position = [panGR translationInView:self.shadeView];

// 手势触摸结束

if (panGR.state == UIGestureRecognizerStateEnded) {

if (- position.x > MAXEXCURSION * 0.5) {

[self hiddenLeftViewAnimation];

} else {

[self showLeftViewAnimation];

}

return;

}

// 判断是否滑出屏幕外

if (position.x < - MAXEXCURSION || position.x > 0) {

return;

}

[self showLeftViewAnimationWithExcursion:MAXEXCURSION + position.x];

}

#pragma mark - Public Methdos

/**

显示左侧视图动画

*/

- (void)showLeftViewAnimation {

WEAKSELF

[UIView animateWithDuration:0.25 animations:^{

weakSelf.transform = CGAffineTransformTranslate(weakSelf.rootViewController.view.transform, MAXEXCURSION, 0);

weakSelf.shadeView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];

[weakSelf addSubview:weakSelf.shadeView];

}];

}

/**

显示左侧视图

@param excursion 偏移大小

*/

- (void)showLeftViewAnimationWithExcursion:(CGFloat)excursion {

self.transform = CGAffineTransformTranslate(self.rootViewController.view.transform, excursion, 0);

self.shadeView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5 * (excursion / MAXEXCURSION)];

if (!self.shadeView.superview) {

[self addSubview:self.shadeView];

}

}

/**

隐藏左侧视图动画

*/

- (void)hiddenLeftViewAnimation {

WEAKSELF

[UIView animateWithDuration:0.25 animations:^{

weakSelf.transform = CGAffineTransformIdentity;

[weakSelf.shadeView removeFromSuperview];

}];

}

#pragma mark - Private Methdos

/**

重写hitTest方法,点击tableView才会响应

*/

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

UIView *view = [super hitTest:point withEvent:event];

if (!view) {

CGPoint newPoint = [self.tableView convertPoint:point fromView:self];

if (CGRectContainsPoint(self.tableView.bounds, newPoint)) {

view = self.tableView;

}

}

return view;

}

#pragma mark - Getters And Setters

- (UITableView *)tableView {

if (!_tableView) {

_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, -MAXEXCURSION, SCREENHEIGHT)];

[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kDBHTableViewCellIdentifier];

_tableView.dataSource = self;

_tableView.delegate = self;

}

return _tableView;

}

- (UIView *)shadeView {

if (!_shadeView) {

_shadeView = [[UIView alloc] initWithFrame:self.bounds];

_shadeView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];

UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToShadeView)];

UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToPanGR:)];

[_shadeView addGestureRecognizer:tapGR];

[_shadeView addGestureRecognizer:panGR];

}

return _shadeView;

}

其次,在主控制器中加上拖动手势,使之看上去看炫

DBHRootViewController.h:

#import

@interface DBHRootViewController : UIViewController

/**

选中行数

*/

@property (nonatomic, assign) NSInteger selectedIndex;

@end

DBHRootViewController.m:

#import "DBHRootViewController.h"

#import "DBHWindow.h"

@interface DBHRootViewController ()

@property (nonatomic, assign) BOOL isBestLeft; // 是否为最左边

@end

@implementation DBHRootViewController

#pragma mark - Lifecycle

- (void)viewDidLoad {

[super viewDidLoad];

self.title = @"侧滑Demo";

self.view.backgroundColor = [UIColor whiteColor];

[self setUI];

}

#pragma mark - UI

- (void)setUI {

UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"showLeftView" style:UIBarButtonItemStylePlain target:self action:@selector(respondsToLeftBarButtonItem)];

self.navigationItem.leftBarButtonItem = leftBarButtonItem;

// 添加拖动手势

UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToPanGR:)];

[self.navigationController.view addGestureRecognizer:panGR];

}

#pragma mark - Event Responds

/**

点击showLeftView按钮

*/

- (void)respondsToLeftBarButtonItem {

DBHWindow *window = (DBHWindow *)[UIApplication sharedApplication].keyWindow;

[window showLeftViewAnimation];

}

/**

拖动手势调用的方法

*/

- (void)respondsToPanGR:(UIPanGestureRecognizer *)panGR {

CGPoint clickPoint = [panGR locationInView:self.navigationController.view];

CGPoint position = [panGR translationInView:self.navigationController.view];

// 手势触摸开始

if (panGR.state == UIGestureRecognizerStateBegan) {

// 判断手势起始点是否在最左边区域

self.isBestLeft = clickPoint.x < LEFTMAXWIDTH;

}

DBHWindow *window = (DBHWindow *)[UIApplication sharedApplication].keyWindow;

// 手势触摸结束

if (panGR.state == UIGestureRecognizerStateEnded) {

if (position.x > MAXEXCURSION * 0.5) {

[window showLeftViewAnimation];

} else {

[window hiddenLeftViewAnimation];

}

return;

}

// 判断是否滑出屏幕外或者拖动手势起始点是否在最左侧区域

if (position.x < 0 || position.x > MAXEXCURSION || !self.isBestLeft) {

return;

}

[window showLeftViewAnimationWithExcursion:position.x];

}

#pragma mark - Getters And Setters

- (void)setSelectedIndex:(NSInteger)selectedIndex {

_selectedIndex = selectedIndex;

UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"点击了第%ld行", _selectedIndex] message:@"" preferredStyle:UIAlertControllerStyleAlert];

[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];

[self presentViewController:alert animated:YES completion:nil];

}

@end

时间原因,加上只是想实现一个侧滑的效果,左侧的显示视图就随意放了一个tableView,这里可以根据自己的需要换成其他视图即可。想看源码的可以点击最下面的地址下载。

Demo地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值