这个是参照鸿洋的android侧滑菜单实现的,同样利用scrollview实现,很简单,这是鸿洋侧滑的实现链接打造最简单的自定义侧滑菜单
第一种测滑
#import <UIKit/UIKit.h>
@interface SlideMenu : UIScrollView
@property (nonatomic, assign) BOOL isMenuOpen;
/**设置菜单和内容*/
-(void)setMenuView:(UIView*)menuView withContentView:(UIView*)contentView;
/**关闭菜单*/
-(void)closeMenuWithAnimation:(BOOL)animated;
/**打开菜单*/
-(void)openMenuWithAnimaton:(BOOL)animated;
/**菜单打开与关闭切换*/
-(void)toggleMenu;
@end
#import "SlideMenu.h"
#define menu_ratio 0.7f
@interface SlideMenu()<UIScrollViewDelegate>
@end
@implementation SlideMenu
{
float _menuWidth;
UIView *_menuViewContainer;
UIView *_contentViewContainer;
UIView *_menuView;
UIView *_contentView;
}
-(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
[self setUp];
}
return self;
}
-(void)setUp
{
_menuViewContainer = [UIView new];
_contentViewContainer = [UIView new];
[self addSubview:_menuViewContainer];
[self addSubview:_contentViewContainer];
self.delegate = self;
//不显示滚动条
self.showsHorizontalScrollIndicator = false;
//不显示弹簧效果
self.bounces = false;
_isMenuOpen = true;
if(!CGRectEqualToRect(self.frame, CGRectZero))
{
[self initFrame];
}
}
-(void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self initFrame];
}
-(void)initFrame
{
//放置菜单的位置
_menuViewContainer.frame = CGRectMake(0, 0, self.frame.size.width * menu_ratio, self.frame.size.height);
_menuWidth = _menuViewContainer.frame.size.width;
//放置content的位置
_contentViewContainer.frame = CGRectMake(CGRectGetMaxX(_menuViewContainer.frame), 0, self.frame.size.width, self.frame.size.height);
//设置可滚动区域
self.contentSize = CGSizeMake(_menuViewContainer.frame.size.width + _contentViewContainer.frame.size.width, 0);
//初始关闭菜单
[self closeMenuWithAnimation:false];
if(_menuView != nil)
{
_menuView.frame = _menuViewContainer.bounds;
}
if(_contentView != nil)
{
_contentView.frame = _contentViewContainer.bounds;
}
}
//设置菜单和内容
-(void)setMenuView:(UIView *)menuView withContentView:(UIView *)contentView
{
//添加菜单
if(_menuView != nil)
{
return;
}
_menuView = menuView;
[_menuViewContainer addSubview:menuView];
//添加内容
if(_contentView != nil)
{
return;
}
_contentView = contentView;
[_contentViewContainer addSubview:contentView];
//设置实际菜单位置,填充菜单容器
_menuView.frame = _menuViewContainer.bounds;
//设置实际内容位置,填充内容容器
_contentView.frame = _contentViewContainer.bounds;
}
//拖动松开时会调用,第二个参数表示拖动松开后是否会自动减速滑动
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
//判断应该显示菜单还是内容
float offset = scrollView.contentOffset.x;
if(decelerate)
{
//如果松开后自动减速滚动,什么也不做
return;
}
if(offset > _menuWidth / 2.0f)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
//判断应该显示菜单还是内容
float offset = scrollView.contentOffset.x;
if(offset > _menuWidth / 2.0f)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
//关闭菜单
-(void)closeMenuWithAnimation:(BOOL)animated
{
_isMenuOpen = false;
[self setContentOffset:CGPointMake(_menuWidth, 0) animated:animated];
}
//打开菜单
-(void)openMenuWithAnimaton:(BOOL)animated
{
_isMenuOpen = true;
[self setContentOffset:CGPointMake(0, 0) animated:animated];
}
//菜单切换
-(void)toggleMenu
{
if(_isMenuOpen)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
第二种侧滑
#import <UIKit/UIKit.h>
@interface SlideMenu2 : UIScrollView
@property (nonatomic, assign) BOOL isMenuOpen;
/**设置菜单和内容*/
-(void)setMenuView:(UIView*)menuView withContentView:(UIView*)contentView;
/**关闭菜单*/
-(void)closeMenuWithAnimation:(BOOL)animated;
/**打开菜单*/
-(void)openMenuWithAnimaton:(BOOL)animated;
/**菜单打开与关闭切换*/
-(void)toggleMenu;
@end
#import "SlideMenu2.h"
#define menu_ratio 0.70f
@interface SlideMenu2()<UIScrollViewDelegate>
@end
@implementation SlideMenu2
{
float _menuWidth;
UIView *_menuViewContainer;
UIView *_contentViewContainer;
UIView *_menuView;
UIView *_contentView;
}
-(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
[self setUp];
}
return self;
}
-(void)setUp
{
_menuViewContainer = [UIView new];
_contentViewContainer = [UIView new];
[self addSubview:_menuViewContainer];
[self addSubview:_contentViewContainer];
self.delegate = self;
//不显示滚动条
self.showsHorizontalScrollIndicator = false;
//不显示弹簧效果
self.bounces = false;
_isMenuOpen = true;
if(!CGRectEqualToRect(self.frame, CGRectZero))
{
[self initFrame];
}
}
-(void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self initFrame];
}
-(void)initFrame
{
//放置菜单的位置
_menuViewContainer.frame = CGRectMake(0, 0, self.frame.size.width * menu_ratio, self.frame.size.height);
_menuWidth = _menuViewContainer.frame.size.width;
//放置content的位置
_contentViewContainer.frame = CGRectMake(CGRectGetMaxX(_menuViewContainer.frame), 0, self.frame.size.width, self.frame.size.height);
//设置可滚动区域
self.contentSize = CGSizeMake(_menuViewContainer.frame.size.width + _contentViewContainer.frame.size.width, 0);
//初始关闭菜单
[self closeMenuWithAnimation:false];
if(_menuView != nil)
{
_menuView.frame = _menuViewContainer.bounds;
}
if(_contentView != nil)
{
_contentView.frame = _contentViewContainer.bounds;
}
}
//设置菜单和内容
-(void)setMenuView:(UIView *)menuView withContentView:(UIView *)contentView
{
//添加菜单
if(_menuView != nil)
{
return;
}
_menuView = menuView;
[_menuViewContainer addSubview:menuView];
//添加内容
if(_contentView != nil)
{
return;
}
_contentView = contentView;
[_contentViewContainer addSubview:contentView];
//设置实际菜单位置,填充菜单容器
_menuView.frame = _menuViewContainer.bounds;
//设置实际内容位置,填充内容容器
_contentView.frame = _contentViewContainer.bounds;
}
//拖动松开时会调用,第二个参数表示拖动松开后是否会自动减速滑动
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
//判断应该显示菜单还是内容
float offset = scrollView.contentOffset.x;
if(decelerate)
{
//如果松开后自动减速滚动,什么也不做
return;
}
if(offset > _menuWidth / 2.0f)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
//滚动停止后调用
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
//判断应该显示菜单还是内容
float offset = scrollView.contentOffset.x;
if(offset > _menuWidth / 2.0f)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
//正在滚动时调用,频繁调用
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//计算菜单移动比例
float ratio = scrollView.contentOffset.x * 1.0f / _menuWidth;
_menuViewContainer.transform = CGAffineTransformMakeTranslation(_menuWidth * ratio, 0);
}
//关闭菜单
-(void)closeMenuWithAnimation:(BOOL)animated
{
_isMenuOpen = false;
[self setContentOffset:CGPointMake(_menuWidth, 0) animated:animated];
}
//打开菜单
-(void)openMenuWithAnimaton:(BOOL)animated
{
_isMenuOpen = true;
[self setContentOffset:CGPointMake(0, 0) animated:animated];
}
//菜单切换
-(void)toggleMenu
{
if(_isMenuOpen)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
@end
仿QQ侧滑
#import <UIKit/UIKit.h>
@interface SlideMenu3 : UIScrollView
@property (nonatomic, assign) BOOL isMenuOpen;
/**设置菜单和内容*/
-(void)setMenuView:(UIView*)menuView withContentView:(UIView*)contentView;
/**关闭菜单*/
-(void)closeMenuWithAnimation:(BOOL)animated;
/**打开菜单*/
-(void)openMenuWithAnimaton:(BOOL)animated;
/**菜单打开与关闭切换*/
-(void)toggleMenu;
@end
#import "SlideMenu3.h"
#define menu_ratio 0.70f
@interface SlideMenu3()<UIScrollViewDelegate>
@end
@implementation SlideMenu3
{
float _menuWidth;
UIView *_menuViewContainer;
UIView *_contentViewContainer;
UIView *_menuView;
UIView *_contentView;
}
-(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
[self setUp];
}
return self;
}
-(void)setUp
{
_menuViewContainer = [UIView new];
_contentViewContainer = [UIView new];
[self addSubview:_menuViewContainer];
[self addSubview:_contentViewContainer];
self.delegate = self;
//这两行代码主要是为了确定缩放点,如果不设置是绕view的中心缩放
// _contentViewContainer.layer.anchorPoint = CGPointMake(0, 0.5f);
// _contentViewContainer.layer.position = CGPointMake(0, 0.5f);
//不显示滚动条
self.showsHorizontalScrollIndicator = false;
//不显示弹簧效果
self.bounces = false;
_isMenuOpen = true;
if(!CGRectEqualToRect(self.frame, CGRectZero))
{
[self initFrame];
}
}
-(void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self initFrame];
}
-(void)initFrame
{
//放置菜单的位置
_menuViewContainer.frame = CGRectMake(0, 0, self.frame.size.width * menu_ratio, self.frame.size.height);
_menuWidth = _menuViewContainer.frame.size.width;
//放置content的位置
_contentViewContainer.frame = CGRectMake(CGRectGetMaxX(_menuViewContainer.frame), 0, self.frame.size.width, self.frame.size.height);
//设置可滚动区域
self.contentSize = CGSizeMake(_menuViewContainer.frame.size.width + _contentViewContainer.frame.size.width, 0);
//初始关闭菜单
[self closeMenuWithAnimation:false];
if(_menuView != nil)
{
_menuView.frame = _menuViewContainer.bounds;
}
if(_contentView != nil)
{
_contentView.frame = _contentViewContainer.bounds;
}
}
//设置菜单和内容
-(void)setMenuView:(UIView *)menuView withContentView:(UIView *)contentView
{
//添加菜单
if(_menuView != nil)
{
return;
}
_menuView = menuView;
[_menuViewContainer addSubview:menuView];
//添加内容
if(_contentView != nil)
{
return;
}
_contentView = contentView;
[_contentViewContainer addSubview:contentView];
//设置实际菜单位置,填充菜单容器
_menuView.frame = _menuViewContainer.bounds;
//设置实际内容位置,填充内容容器
_contentView.frame = _contentViewContainer.bounds;
}
//拖动松开时会调用,第二个参数表示拖动松开后是否会自动减速滑动
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
//判断应该显示菜单还是内容
float offset = scrollView.contentOffset.x;
if(decelerate)
{
//如果松开后自动减速滚动,什么也不做
return;
}
if(offset > _menuWidth / 2.0f)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
//正在滚动时调用,频繁调用
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//计算菜单移动比例
float ratio = scrollView.contentOffset.x * 1.0f / _menuWidth;
//计算缩放比例
float contentScale = ratio * 0.2f + 0.8f;
float menuScale = 1.0f - ratio * 0.3f;
float alpha = 1.0f - ratio * 0.4f;
//缩放内容区
_contentViewContainer.transform = CGAffineTransformMakeScale(contentScale, contentScale);
//处理菜单
CGAffineTransform scaleTransform = CGAffineTransformMakeScale(menuScale, menuScale);
_menuViewContainer.transform = CGAffineTransformTranslate(scaleTransform,_menuWidth * ratio * 0.6, 0.0f);
//菜单alpha
_menuViewContainer.alpha = alpha;
}
//滚动停止后调用
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
//判断应该显示菜单还是内容
float offset = scrollView.contentOffset.x;
if(offset > _menuWidth / 2.0f)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
//关闭菜单
-(void)closeMenuWithAnimation:(BOOL)animated
{
_isMenuOpen = false;
[self setContentOffset:CGPointMake(_menuWidth, 0) animated:animated];
}
//打开菜单
-(void)openMenuWithAnimaton:(BOOL)animated
{
_isMenuOpen = true;
[self setContentOffset:CGPointMake(0, 0) animated:animated];
}
//菜单切换
-(void)toggleMenu
{
if(_isMenuOpen)
{
[self closeMenuWithAnimation:true];
}
else
{
[self openMenuWithAnimaton:true];
}
}
@end