iOS-MMDrawerController的使用【抽屉视图+(SUNSlideSwitchView)进度条手势滑动】转
下载网站:https://github.com/mutualmobile/MMDrawerController
首先,到下载网址下载MMDrawerController,将文件导入工程,里面有:
MMDrawerController+Subclass.h
MMDrawerBarButtonItem.h
MMDrawerBarButtonItem.m
MMDrawerController.h
MMDrawerController.m
MMDrawerVisualState.h
MMDrawerVisualState.m
UIViewController+MMDrawerController.h
UIViewController+MMDrawerController.m
然后再引入两个文件SUNSlideSwitchView.h和SUNSlideSwitchView.m即可。
下面将阐述如何调用里面的方法:
第一,自定义一个Viewcontroler叫GGLeftMenuViewController,继承UIViewController.
自定义SUNViewController继承MMDrawerController。
在AppDelegate.m里面,
#import "AppDelegate.h"
#import "GGLeftMenuViewController.h"
#import "MMDrawerController.h"
#import "MMDrawerVisualState.h"
static const CGFloat kPublicLeftMenuWidth = 180.0f;
@implementation SUNAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
GGLeftMenuViewController *leftVC = [[GGLeftMenuViewController alloc]
initWithNibName:@"SUNLeftMenuViewController"
bundle:nil];
SUNViewController * drawerController = [[SUNViewController alloc]
initWithCenterViewController:leftVC.navSlideSwitchVC
leftDrawerViewController:leftVC
rightDrawerViewController:nil];
[drawerController setMaximumLeftDrawerWidth:kPublicLeftMenuWidth];
[drawerController setOpenDrawerGestureModeMask:MMOpenDrawerGestureModeAll];
[drawerController setCloseDrawerGestureModeMask:MMCloseDrawerGestureModeAll];
[drawerController setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) {
MMDrawerControllerDrawerVisualStateBlock block;
block = [MMDrawerVisualState parallaxVisualStateBlockWithParallaxFactor:2.0];
block(drawerController, drawerSide, percentVisible);
}];
[self.window setRootViewController:drawerController];
[self.window makeKeyAndVisible];
return YES;
}
自定义SUNSlideSwitchView:UIView 手势左右滑动视图、
在SUNSlideSwitchView.h
#import <UIKit/UIKit.h>
@protocol SUNSlideSwitchViewDelegate;
@interface SUNSlideSwitchView : UIView<UIScrollViewDelegate>
{
UIScrollView *_rootScrollView; //主视图
UIScrollView *_topScrollView; //顶部页签视图
CGFloat _userContentOffsetX;
BOOL _isLeftScroll; //是否左滑动
BOOL _isRootScroll; //是否主视图滑动
BOOL _isBuildUI; //是否建立了ui
NSInteger _userSelectedChannelID; //点击按钮选择名字ID
UIImageView *_shadowImageView;
UIImage *_shadowImage;
UIColor *_tabItemNormalColor; //正常时tab文字颜色
UIColor *_tabItemSelectedColor; //选中时tab文字颜色
UIImage *_tabItemNormalBackgroundImage; //正常时tab的背景
UIImage *_tabItemSelectedBackgroundImage; //选中时tab的背景
NSMutableArray *_viewArray; //主视图的子视图数组
UIButton *_rigthSideButton; //右侧按钮
__weak id<SUNSlideSwitchViewDelegate> _slideSwitchViewDelegate;
}
@property (nonatomic, strong) IBOutlet UIScrollView *rootScrollView;
@property (nonatomic, strong) IBOutlet UIScrollView *topScrollView;
@property (nonatomic, assign) CGFloat userContentOffsetX;
@property (nonatomic, assign) NSInteger userSelectedChannelID;
@property (nonatomic, assign) NSInteger scrollViewSelectedChannelID;
@property (nonatomic, weak) IBOutlet id<SUNSlideSwitchViewDelegate> slideSwitchViewDelegate;
@property (nonatomic, strong) UIColor *tabItemNormalColor;
@property (nonatomic, strong) UIColor *tabItemSelectedColor;
@property (nonatomic, strong) UIImage *tabItemNormalBackgroundImage;
@property (nonatomic, strong) UIImage *tabItemSelectedBackgroundImage;
@property (nonatomic, strong) UIImage *shadowImage;
@property (nonatomic, strong) NSMutableArray *viewArray;
@property (nonatomic, strong) IBOutlet UIButton *rigthSideButton;
/*!
* @method 创建子视图UI
* @abstract
* @discussion
* @param
* @result
*/
- (void)buildUI;
/*!
* @method 通过16进制计算颜色
* @abstract
* @discussion
* @param 16机制
* @result 颜色对象
*/
+ (UIColor *)colorFromHexRGB:(NSString *)inColorString;
@end
@protocol SUNSlideSwitchViewDelegate <NSObject>
@required
/*!
* @method 顶部tab个数
* @abstract
* @discussion
* @param 本控件
* @result tab个数
*/
- (NSUInteger)numberOfTab:(SUNSlideSwitchView *)view;
/*!
* @method 每个tab所属的viewController
* @abstract
* @discussion
* @param tab索引
* @result viewController
*/
- (UIViewController *)slideSwitchView:(SUNSlideSwitchView *)view viewOfTab:(NSUInteger)number;
@optional
/*!
* @method 滑动左边界时传递手势
* @abstract
* @discussion
* @param 手势
* @result
*/
- (void)slideSwitchView:(SUNSlideSwitchView *)view panLeftEdge:(UIPanGestureRecognizer*) panParam;
/*!
* @method 滑动右边界时传递手势
* @abstract
* @discussion
* @param 手势
* @result
*/
- (void)slideSwitchView:(SUNSlideSwitchView *)view panRightEdge:(UIPanGestureRecognizer*) panParam;
/*!
* @method 点击tab
* @abstract
* @discussion
* @param tab索引
* @result
*/
- (void)slideSwitchView:(SUNSlideSwitchView *)view didselectTab:(NSUInteger)number;
@end
在SUNSlideSwitchView.m中
#import "SUNSlideSwitchView.h"
static const CGFloat kHeightOfTopScrollView = 44.0f;
static const CGFloat kWidthOfButtonMargin = 16.0f;
static const CGFloat kFontSizeOfTabButton = 17.0f;
static const NSUInteger kTagOfRightSideButton = 999;
@implementation SUNSlideSwitchView
#pragma mark - 初始化参数
- (void)initValues
{
//创建顶部可滑动的tab
_topScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, kHeightOfTopScrollView)];
_topScrollView.delegate = self;
_topScrollView.backgroundColor = [UIColor yellowColor];
_topScrollView.pagingEnabled = NO;
_topScrollView.showsHorizontalScrollIndicator = NO;
_topScrollView.showsVerticalScrollIndicator = NO;
_topScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self addSubview:_topScrollView];
_userSelectedChannelID = 100;
//创建主滚动视图
_rootScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, kHeightOfTopScrollView, self.bounds.size.width, self.bounds.size.height - kHeightOfTopScrollView)];
_rootScrollView.delegate = self;
_rootScrollView.pagingEnabled = YES;
_rootScrollView.userInteractionEnabled = YES;
_rootScrollView.bounces = NO;
_rootScrollView.showsHorizontalScrollIndicator = NO;
_rootScrollView.showsVerticalScrollIndicator = NO;
_rootScrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
_userContentOffsetX = 0;
[_rootScrollView.panGestureRecognizer addTarget:self action:@selector(scrollHandlePan:)];
[self addSubview:_rootScrollView];
_viewArray = [[NSMutableArray alloc] init];
_isBuildUI = NO;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self initValues];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self initValues];
}
return self;
}
#pragma mark getter/setter
- (void)setRigthSideButton:(UIButton *)rigthSideButton
{
UIButton *button = (UIButton *)[self viewWithTag:kTagOfRightSideButton];
[button removeFromSuperview];
rigthSideButton.tag = kTagOfRightSideButton;
_rigthSideButton = rigthSideButton;
[self addSubview:_rigthSideButton];
}
#pragma mark - 创建控件
//当横竖屏切换时可通过此方法调整布局
- (void)layoutSubviews
{
//创建完子视图UI才需要调整布局
if (_isBuildUI) {
//如果有设置右侧视图,缩小顶部滚动视图的宽度以适应按钮
if (self.rigthSideButton.bounds.size.width > 0) {
_rigthSideButton.frame = CGRectMake(self.bounds.size.width - self.rigthSideButton.bounds.size.width, 0,
_rigthSideButton.bounds.size.width, _topScrollView.bounds.size.height);
_topScrollView.frame = CGRectMake(0, 0,
self.bounds.size.width - self.rigthSideButton.bounds.size.width, kHeightOfTopScrollView);
}
//更新主视图的总宽度
_rootScrollView.contentSize = CGSizeMake(self.bounds.size.width * [_viewArray count], 0);
//更新主视图各个子视图的宽度
for (int i = 0; i < [_viewArray count]; i++) {
UIViewController *listVC = _viewArray[i];
listVC.view.frame = CGRectMake(0+_rootScrollView.bounds.size.width*i, 0,
_rootScrollView.bounds.size.width, _rootScrollView.bounds.size.height);
}
//滚动到选中的视图
[_rootScrollView setContentOffset:CGPointMake((_userSelectedChannelID - 100)*self.bounds.size.width, 0) animated:NO];
//调整顶部滚动视图选中按钮位置
UIButton *button = (UIButton *)[_topScrollView viewWithTag:_userSelectedChannelID];
[self adjustScrollViewContentX:button];
}
}
/*!
* @method 创建子视图UI
* @abstract
* @discussion
* @param
* @result
*/
- (void)buildUI
{
NSUInteger number = [self.slideSwitchViewDelegate numberOfTab:self];
for (int i=0; i<number; i++) {
UIViewController *vc = [self.slideSwitchViewDelegate slideSwitchView:self viewOfTab:i];
[_viewArray addObject:vc];
[_rootScrollView addSubview:vc.view];
}
[self createNameButtons];
//选中第一个view
if (self.slideSwitchViewDelegate && [self.slideSwitchViewDelegate respondsToSelector:@selector(slideSwitchView:didselectTab:)]) {
[self.slideSwitchViewDelegate slideSwitchView:self didselectTab:_userSelectedChannelID - 100];
}
_isBuildUI = YES;
//创建完子视图UI才需要调整布局
[self setNeedsLayout];
}
/*!
* @method 初始化顶部tab的各个按钮
* @abstract
* @discussion
* @param
* @result
*/
- (void)createNameButtons
{
_shadowImageView = [[UIImageView alloc] init];
[_shadowImageView setImage:_shadowImage];
[_topScrollView addSubview:_shadowImageView];
//顶部tabbar的总长度
CGFloat topScrollViewContentWidth = kWidthOfButtonMargin;
//每个tab偏移量
CGFloat xOffset = kWidthOfButtonMargin;
for (int i = 0; i < [_viewArray count]; i++) {
UIViewController *vc = _viewArray[i];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGSize textSize = [vc.title sizeWithFont:[UIFont systemFontOfSize:kFontSizeOfTabButton]
constrainedToSize:CGSizeMake(_topScrollView.bounds.size.width, kHeightOfTopScrollView)
lineBreakMode:NSLineBreakByTruncatingTail];
//累计每个tab文字的长度
topScrollViewContentWidth += kWidthOfButtonMargin+textSize.width;
//设置按钮尺寸
[button setFrame:CGRectMake(xOffset,0,
textSize.width, kHeightOfTopScrollView)];
//计算下一个tab的x偏移量
xOffset += textSize.width + kWidthOfButtonMargin;
[button setTag:i+100];
if (i == 0) {
_shadowImageView.frame = CGRectMake(kWidthOfButtonMargin, 0, textSize.width, _shadowImage.size.height);
button.selected = YES;
}
[button setTitle:vc.title forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:kFontSizeOfTabButton];
[button setTitleColor:self.tabItemNormalColor forState:UIControlStateNormal];
[button setTitleColor:self.tabItemSelectedColor forState:UIControlStateSelected];
[button setBackgroundImage:self.tabItemNormalBackgroundImage forState:UIControlStateNormal];
[button setBackgroundImage:self.tabItemSelectedBackgroundImage forState:UIControlStateSelected];
[button addTarget:self action:@selector(selectNameButton:) forControlEvents:UIControlEventTouchUpInside];
[_topScrollView addSubview:button];
}
//设置顶部滚动视图的内容总尺寸
_topScrollView.contentSize = CGSizeMake(topScrollViewContentWidth, kHeightOfTopScrollView);
}
#pragma mark - 顶部滚动视图逻辑方法
/*!
* @method 选中tab时间
* @abstract
* @discussion
* @param 按钮
* @result
*/
- (void)selectNameButton:(UIButton *)sender
{
//如果点击的tab文字显示不全,调整滚动视图x坐标使用使tab文字显示全
[self adjustScrollViewContentX:sender];
//如果更换按钮
if (sender.tag != _userSelectedChannelID) {
//取之前的按钮
UIButton *lastButton = (UIButton *)[_topScrollView viewWithTag:_userSelectedChannelID];
lastButton.selected = NO;
//赋值按钮ID
_userSelectedChannelID = sender.tag;
}
//按钮选中状态
if (!sender.selected) {
sender.selected = YES;
[UIView animateWithDuration:0.25 animations:^{
[_shadowImageView setFrame:CGRectMake(sender.frame.origin.x, 0, sender.frame.size.width, _shadowImage.size.height)];
} completion:^(BOOL finished) {
if (finished) {
//设置新页出现
if (!_isRootScroll) {
[_rootScrollView setContentOffset:CGPointMake((sender.tag - 100)*self.bounds.size.width, 0) animated:YES];
}
_isRootScroll = NO;
if (self.slideSwitchViewDelegate && [self.slideSwitchViewDelegate respondsToSelector:@selector(slideSwitchView:didselectTab:)]) {
[self.slideSwitchViewDelegate slideSwitchView:self didselectTab:_userSelectedChannelID - 100];
}
}
}];
}
//重复点击选中按钮
else {
}
}
/*!
* @method 调整顶部滚动视图x位置
* @abstract
* @discussion
* @param
* @result
*/
- (void)adjustScrollViewContentX:(UIButton *)sender
{
//如果 当前显示的最后一个tab文字超出右边界
if (sender.frame.origin.x - _topScrollView.contentOffset.x > self.bounds.size.width - (kWidthOfButtonMargin+sender.bounds.size.width)) {
//向左滚动视图,显示完整tab文字
[_topScrollView setContentOffset:CGPointMake(sender.frame.origin.x - (_topScrollView.bounds.size.width- (kWidthOfButtonMargin+sender.bounds.size.width)), 0) animated:YES];
}
//如果 (tab的文字坐标 - 当前滚动视图左边界所在整个视图的x坐标) < 按钮的隔间 ,代表tab文字已超出边界
if (sender.frame.origin.x - _topScrollView.contentOffset.x < kWidthOfButtonMargin) {
//向右滚动视图(tab文字的x坐标 - 按钮间隔 = 新的滚动视图左边界在整个视图的x坐标),使文字显示完整
[_topScrollView setContentOffset:CGPointMake(sender.frame.origin.x - kWidthOfButtonMargin, 0) animated:YES];
}
}
#pragma mark 主视图逻辑方法
//滚动视图开始时
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if (scrollView == _rootScrollView) {
_userContentOffsetX = scrollView.contentOffset.x;
}
}
//滚动视图结束
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView == _rootScrollView) {
//判断用户是否左滚动还是右滚动
if (_userContentOffsetX < scrollView.contentOffset.x) {
_isLeftScroll = YES;
}
else {
_isLeftScroll = NO;
}
}
}
//滚动视图释放滚动
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (scrollView == _rootScrollView) {
_isRootScroll = YES;
//调整顶部滑条按钮状态
int tag = (int)scrollView.contentOffset.x/self.bounds.size.width +100;
UIButton *button = (UIButton *)[_topScrollView viewWithTag:tag];
[self selectNameButton:button];
}
}
//传递滑动事件给下一层
-(void)scrollHandlePan:(UIPanGestureRecognizer*) panParam
{
//当滑道左边界时,传递滑动事件给代理
if(_rootScrollView.contentOffset.x <= 0) {
if (self.slideSwitchViewDelegate
&& [self.slideSwitchViewDelegate respondsToSelector:@selector(slideSwitchView:panLeftEdge:)]) {
[self.slideSwitchViewDelegate slideSwitchView:self panLeftEdge:panParam];
}
} else if(_rootScrollView.contentOffset.x >= _rootScrollView.contentSize.width - _rootScrollView.bounds.size.width) {
if (self.slideSwitchViewDelegate
&& [self.slideSwitchViewDelegate respondsToSelector:@selector(slideSwitchView:panRightEdge:)]) {
[self.slideSwitchViewDelegate slideSwitchView:self panRightEdge:panParam];
}
}
}
#pragma mark - 工具方法
/*!
* @method 通过16进制计算颜色
* @abstract
* @discussion
* @param 16机制
* @result 颜色对象
*/
+ (UIColor *)colorFromHexRGB:(NSString *)inColorString
{
UIColor *result = nil;
unsigned int colorCode = 0;
unsigned char redByte, greenByte, blueByte;
if (nil != inColorString)
{
NSScanner *scanner = [NSScanner scannerWithString:inColorString];
(void) [scanner scanHexInt:&colorCode]; // ignore error
}
redByte = (unsigned char) (colorCode >> 16);
greenByte = (unsigned char) (colorCode >> 8);
blueByte = (unsigned char) (colorCode); // masks off high bits
result = [UIColor
colorWithRed: (float)redByte / 0xff
green: (float)greenByte/ 0xff
blue: (float)blueByte / 0xff
alpha:1.0];
return result;
}
@end
iOS-MMDrawerController的使用【抽屉视图+(SUNSlideSwitchView)进度条手势滑动】转的更多相关文章
- 第三方MMDrawerController的使用 抽屉视图+(SUNSlideSwitchView)进度条手势滑动效果实现
下载网站:https://github.com/mutualmobile/MMDrawerController 首先,到下载网址下载MMDrawerController,将文件导入工程,里面有: MM ...
- 使用原生JS+CSS或HTML5实现简单的进度条和滑动条效果(精问)
使用原生JS+CSS或HTML5实现简单的进度条和滑动条效果(精问) 一.总结 一句话总结:进度条动画效果用animation,自动效果用setIntelval 二.使用原生JS+CSS或HTML5实 ...
- 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条
http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...
- iOS之小功能模块--彩虹动画进度条学习和自主封装改进
前言: 首先展示一下这个iOS小示例的彩色进度条动画效果: 阅读本文先说说好处:对于基础不好的读者,可以直接阅读文末尾的"如何使用彩虹动画进度条"章节,然后将我封装好的这个功能模块 ...
- ios开发之--给WebView加载进度条
不是新东西,就是在项目里面用到H5页面的时候,中间加载延迟的时候,在最上面加载一个进度条,代码如下: // 获取屏幕 宽度.高度 bounds就是屏幕的全部区域 #define KDeviceWidt ...
- 【iOS实现一个颜色渐变的弧形进度条】
在Github上看到一些进度条的功能,都是通过Core Graph来实现.无所谓正确与否,但是开发效率明显就差很多了,而且运行效率还是值得考究的.其实使用苹果提供的Core Animation能够非常 ...
- iOS 获取内存大小使用情况(进度条显示)
一.获取设备内存大小方法 //返回存储内存占用比例 - (NSString *)getFreeDiskspaceRate{ float totalSpace; .f; NSError *error = ...
- IOS第16天(2,Quartz2D下载进度条)
*************自定义下载的view的方法 #import "HMProgressView.h" @interface HMProgressView() @propert ...
- WPF进度条系列①滑动小圆点
写在之前: 关于WPF的样式,我也是学习了很多朋友的文章才有了下面的东西,因为时间有些久远 & 备份的链接也都不在了. 所以,究竟是看过哪些文章,也是记不清楚了…… 请见谅. ------- ...
随机推荐
- 配置基于centos下的远程Jupyter Notebook访问
最近在学习一些服务器上的操作,学着熟悉Liunx系统,记录下自己踩过的坑吧 1.开机后更新系统: yum -y upgrade yum - y update 2.查看已安装的应用 yum list 3 ...
- 【NOIP/CSP2019】D2T1 Emiya 家今天的饭
这个D2T1有点难度啊 原题: 花了我一下午的时间,作为D2T1的确反常 条件很奇怪,感觉不太直观,于是看数据范围先写了个暴力 写暴力的时候我就注意到了之前没有仔细想过的点,烹饪方式必须不同 虽然a很 ...
- Python基础之类
一.摘要 面向对象编程 是最有效的软件编写方法之一.在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象.编写类时,你定义一大类对象都有的通用行为.基于类创建对象 时,每个对 ...
- Charles----伪造手机端的request和reponse参数
使用场景: 在测试中通过伪造reponse数据来模拟某些测试场景,如下截图.要求:通过修改reponse中的值,再次请求修改7为100,只是会显示为99+ 实现方式: 1.通过breakpoints来 ...
- 如何比较js 浮点数
浮点数的定义,非整数的Number类型无法用 ==(===也不行) 来比较,这就是为什么在JavaScript中,0.1+0.2不能=0.3: console.log( 0.1 + 0.2 == 0. ...
- SpringBoot启动过程原理(转)
1.1 Springboot启动: @SpringBootApplication public class ServerApplication { public static void main(St ...
- 关于不用Hashtable
hashmap 与hashtable 很类似,主要区别是hashtable 有用synchronized进行线程同步,hashmap没有.然而,建议少用hashtable,在单线程中,无需做线程控制, ...
- ueditor实现ctrl+v粘贴word图片并上传
图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码 目前限chrome浏览器使用,但是项目要求需要支持所有的浏览器,包括Windows和macOS系统.没有办 ...
- python print import使用
>>> print("aaaa","bbbb")aaaa bbbb>>> print(1, 2, 3)1 2 3 为模块提供 ...
- 使用scp上传ssh公钥到服务器
$ scp ~/.ssh/id_rsa.pub root@xxx.xxx.xxx.xxx:.ssh/id_rsa.pub $ ssh root@xxx.xxx.xxx.xxx $ cat ~/.ssh ...