项目中要实现从Controller左侧滑出菜单。原本打算找开发网站上别人封装好的库来用,后来在网上找了七、八个别人写的侧滑菜单试用后,发现不是不适合、不好用,就是写的太复杂看不懂。于是只能自己写了,其实也不算太难。
效果图:
实现代码:
创建菜单控件LeftProfileView,然后在 .h 文件里
#import
@interface LeftProfileView : UIView
//从左侧滑出的菜单栏
@property (nonatomic,strong) UIView *leftPopView;
/**
菜单弹出的方法
*/
- (void)show;
@end
在 LeftProfileView.m 里
#import "LeftProfileView.h"
#import "LeftMenuCell.h"
#import "PersonalAchievementsController.h"
#import "TabBarController.h"
#import "EditorController.h"
#import "MyServicesController.h"
#import "SystemConfigController.h"
#import "ManualController.h"
@interface LeftProfileView ()
@property (nonatomic,strong) UITableView *tableView;
@property (nonatomic,strong) UIImageView *avatar;
@property (nonatomic,strong) UILabel *nickNameLbl;
@end
@implementation LeftProfileView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [COLOR(blackColor) colorWithAlphaComponent:0.4];
[self setUpUI];
}
return self;
}
- (void)setUpUI
{
UIView *bgView = [HELPER viewWithSuperView:self backgroundColor:COLOR(clearColor) andMasonryBlock:^(MASConstraintMaker * _Nonnull make) {
make.edges.equalTo(self);
}];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(selfDidTap:)];
[bgView addGestureRecognizer:tap];
//左滑出来的视图
self.leftPopView = [HELPER viewWithSuperView:self backgroundColor:RGBOF(0xF0F0F0) andMasonryBlock:^(MASConstraintMaker * _Nonnull make) {
make.top.bottom.equalTo(@0);
make.right.equalTo(self.mas_left);
make.width.equalTo(@(240 * SCREEN_WIDTH/375));
}];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panOnLeftPopView:)];
[self.leftPopView addGestureRecognizer:pan];
//给左滑出来的视图上添加tableView
self.tableView = [self tableViewWithSuperView:self.leftPopView style:UITableViewStyleGrouped backgroundColor:COLOR(clearColor) target:self andMasonryBlock:^(MASConstraintMaker * _Nonnull make) {
make.left.right.top.bottom.equalTo(@0);
}];
[self layoutIfNeeded];
UIView *tableHeader = [HELPER viewWithSuperView:nil backgroundColor:COLOR(clearColor) andMasonryBlock:nil];
tableHeader.frame = FRAME(0, 0, self.tableView.mj_w, 180*[HELPER verticalScale]);
[HELPER imageViewWithSuperView:tableHeader backgroundColor:SPLIT_COLOR image:nil andMasonryBlock:^(MASConstraintMaker * _Nonnull make) {
make.height.equalTo(@0.5);
make.left.right.bottom.equalTo(@0);
}];
self.tableView.tableHeaderView = tableHeader;
UITapGestureRecognizer *headerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(headerTapAction:)];
[tableHeader addGestureRecognizer:headerTap];
//头像
_avatar = [HELPER imageViewWithSuperView:tableHeader backgroundColor:COLOR(clearColor) image:IMG(@"头像") andMasonryBlock:^(MASConstraintMaker * _Nonnull make) {
make.size.mas_equalTo(CGSizeMake(60, 60));
make.centerY.equalTo(tableHeader);
make.left.equalTo(@30);
}];
_avatar.layer.cornerRadius = 30.0;
_avatar.layer.masksToBounds = YES;
//昵称
_nickNameLbl = [HELPER labelWithSuperView:tableHeader backgroundColor:COLOR(clearColor) text:@"三一方圆" textAlignment:NSTextAlignmentLeft textColor:TITLE_BLACK fontSize:18 numberOfLines:1 andMasonryBlock:^(MASConstraintMaker * _Nonnull make) {
make.height.equalTo(@19);
make.centerY.equalTo(tableHeader);
make.left.equalTo(self.avatar.mas_right).offset(20);
make.right.equalTo(@-20);
}];
}
- (UITableView *)tableViewWithSuperView:(UIView *)superView style:(UITableViewStyle)style backgroundColor:(UIColor *)bgColor target:(id)target andMasonryBlock:(MasonryBlock)masonryBlock
{
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectZero style:style];
tableView.backgroundColor = bgColor;
tableView.delegate = target;
tableView.dataSource = target;
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.estimatedRowHeight = 0;
tableView.showsVerticalScrollIndicator = NO;
tableView.bounces = NO;
[superView addSubview:tableView];
if (masonryBlock) {
[tableView mas_makeConstraints:^(MASConstraintMaker *make) {
masonryBlock(make);
}];
}
return tableView;
}
#pragma mark -
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 4;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
LeftMenuCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:@"LeftMenuCell" owner:nil options:nil] firstObject];
}
cell.dataIndexPath = indexPath;
[cell cellAddData];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 62;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0.001;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 19;
}
-(UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return nil;
}
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return nil;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {//个人成就
[self dismiss];
PersonalAchievementsController *personalAchievementsVC = [PersonalAchievementsController new];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:personalAchievementsVC];
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
TabBarController *tabBarVC = (TabBarController *)appDelegate.window.rootViewController;
[tabBarVC presentViewController:nav animated:YES completion:nil];
}else if (indexPath.row == 1){//我的服务
[self dismiss];
MyServicesController *myServicesVC = [MyServicesController new];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:myServicesVC];
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
TabBarController *tabBarVC = (TabBarController *)appDelegate.window.rootViewController;
[tabBarVC presentViewController:nav animated:YES completion:nil];
}else if (indexPath.row == 2){//系统设置
[self dismiss];
SystemConfigController *systemConfigVC = [SystemConfigController new];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:systemConfigVC];
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
TabBarController *tabBarVC = (TabBarController *)appDelegate.window.rootViewController;
[tabBarVC presentViewController:nav animated:YES completion:nil];
}else{//使用手册
[self dismiss];
ManualController *manualVC = [ManualController new];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:manualVC];
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
TabBarController *tabBarVC = (TabBarController *)appDelegate.window.rootViewController;
[tabBarVC presentViewController:nav animated:YES completion:nil];
}
}
#pragma mark - 点击阴影处
- (void)selfDidTap:(UITapGestureRecognizer *)tap
{
[self dismiss];
}
#pragma mark - 点击头部编辑资料
- (void)headerTapAction:(UITapGestureRecognizer *)tap
{
[self dismiss];
EditorController *editorVC = [EditorController new];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:editorVC];
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
UITabBarController *tabBarVC = (UITabBarController *)appDelegate.window.rootViewController;
[tabBarVC presentViewController:nav animated:YES completion:nil];
}
#pragma mark - 弹出左滑菜单
- (void)show
{
[[UIApplication sharedApplication].keyWindow addSubview:self];
[self layoutIfNeeded];
[UIView animateWithDuration:0.3 animations:^{
[self.leftPopView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.equalTo(@0);
make.width.equalTo(@(240 * SCREEN_WIDTH/375));
}];
[self layoutIfNeeded];
}];
}
#pragma mark - 菜单消失
- (void)dismiss
{
[UIView animateWithDuration:0.3 animations:^{
[self.leftPopView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.equalTo(@0);
make.right.equalTo(self.mas_left);
make.width.equalTo(@(240 * SCREEN_WIDTH/375));
}];
[self layoutIfNeeded];
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
#pragma mark - 左滑视图的拖动手势
- (void)panOnLeftPopView:(UIPanGestureRecognizer *)pan
{
CGPoint translationPoint = [pan translationInView:self.leftPopView];
[pan setTranslation:CGPointZero inView:self.leftPopView];
if (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged) {
if (translationPoint.x < 0) {
//向左滑动时
CGFloat tempX = CGRectGetMinX(self.leftPopView.frame) + translationPoint.x;
self.leftPopView.frame = CGRectMake(tempX, 0, CGRectGetWidth(self.leftPopView.frame), CGRectGetHeight(self.leftPopView.frame));
}else{
//向右滑动时
return;
}
}else{
//当左滑视图被拖动的距离小于左滑视图的三分之一宽度时,停止手势让视图恢复原状
if (CGRectGetMinX(self.leftPopView.frame) >= -CGRectGetWidth(self.leftPopView.frame)*0.3) {
[UIView animateWithDuration:0.2 animations:^{
self.leftPopView.frame = CGRectMake(0, 0, CGRectGetWidth(self.leftPopView.frame), CGRectGetHeight(self.leftPopView.frame));
}];
}else{
//当左滑视图被拖动的距离大于左滑视图的三分之一宽度时,停止手势让视图消失
[self dismiss];
}
}
}
@end