iOS侧滑菜单-完全解耦-一行调用

DYLeftSlipManager

一行代码实现侧滑。完全解耦,两个界面之间不需要有任何耦合。基于控制器自定义转场。

Github:https://github.com/maybeisyi/DYLeftSlipManager
先上图:

DYLeftSlipManager.gif

使用:

导入#import "DYLeftSlipManager.h"

// 注意这个控制器是右滑视图控制器,由于完全解耦,所以在DYLeftSlipManager内部是对该控制器强引用防止销毁。

LeftTableViewController *leftVC = [LeftTableViewController new];

[[DYLeftSlipManager sharedManager] setLeftViewController:leftVC coverViewController:self];

// 这个self是覆盖在右滑视图上层的控制器,一般应用中就是UITabbarController

嗯哼。是完全解耦的,你可以在任意地方调用这两句代码即可。
具体实现请看代码(基于控制器转场,并非 视图+手势 )。

相对于网上其他DEMO来说,本例是利用了控制器转场实现的,其他DEMO基本都是View上加侧滑View,这样的话两个界面之间耦合度太高,两个View都归一个C管,不能忍~~~本例就是两个控制器,各管各的业务。

本例的简析将在后续更新到简书,目前简析可在本人博客查看:daiyi.pro

——————————————我是分割线————————————————

标题是简析,不是解析

所以我只谈思路,不谈详细实现

DYLeftSlipManager是一个侧滑菜单组件,它与别的侧滑菜单不同的是,它将“侧面菜单”以及“主页面”之间完全解耦合。

GitHub地址:https://github.com/maybeisyi/DYLeftSlipManager

之前在各大论坛上看到的侧滑菜单,各种仿QQ侧滑菜单,仿XX侧滑等等,均是在同一个ViewController(以下用VC代替)中,添加一个侧面的视图,然后通过手势balabala的。能用吗?当然能用,只要你不嫌你的VC够臃肿。

侧滑菜单页面的内容往往和主页面的内容关联度不大(部分应用中也有见到是有关联的),一般来说都是可以独立为一块业务的(有关联的基本也能抽象为一块独立业务)。在这种场景下,你认为两个业务同写在一个VC里真的好吗?

所以就有了这个轮子。

轮子思路

1. 如何抽象出这部分的业务?

业务的抽象还是需要靠类(甚至于模块)来进行划分。

2. 如何分离出这部分页面?

页面的分离,要么是自定义view,要么是另开一个VC。

自定义view可以实现页面的分离,但是业务逻辑很难全都塞入view中进行管理,因为业务一般是VC或者单独的业务类来进行管理。所以另开一个VC是目前较佳的选择。

3. 如何在当前侧滑的场景下另开一个VC?

首先不要将ViewController和view在脑海中混在一起,不要将VC当做view。VC是一个抽象的内容,只是一堆代码,你是看不见VC的,App上你看见的才是真真切切的view,只不过VC通常作为一个“完整页面(一个手机屏幕大小)”的“容器”存在而已。所谓“容器”,你理解成view是VC的一个属性即可。

为了帮助你理解VC和view的关系,这里我举个简单的小例子:

这里我自定义一个继承自NSObject的类:MyDog(用这个名字是为了有别于VC,这就是一条啊,没错!

@interface MyDog : NSObject

@property (nonatomic, strong) UIView *view;

@end
@implementation MyDog

- (instancetype)init {
    if ((self = [super init])) {
        [self loadView];
    }
    return self;
}

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [self viewDidLoad];
}

- (void)viewDidLoad {
    // balabala
    [self viewWillAppear];
}

- (void)viewWillAppear {
    // balabala
    [self viewDidAppear];
}

- (void)viewDidAppear {
    // balabala
}

@end

这里的狗,含有一个view的属性,还自定义了一些和VC“很像”的方法。

到这里应该没问题。

然后我们在默认的ViewController.m中,addSubview,把狗的view显示出来:

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    MyDog *dog = [[MyDog alloc] init];
    dog.view.frame = CGRectMake(100, 100, 100, 100);
    [self.view addSubview:dog.view];
}

@end

没问题吧,狗的view确实显示出来了吧?那么,狗有个view,新建一个VC也有个view,我们是不是可以把dog换成VC呢?

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIViewController *VC = [[UIViewController alloc] init];
    VC.view.frame = CGRectMake(100, 100, 100, 100);
    VC.view.backgroundColor = [UIColor redColor];
    [self.view addSubview:VC.view];
}

OK吧?现在你想清楚VC和view的关系了吧?

你没想清楚MyDog和VC的关系?这么说把,Dog无法知道view在系统中何时willAppear、DidAppear等节点,所以无法精确的管理view的生命周期,但是VC可以,因为VC是苹果提供的类,它的名字是“UIViewController”,也就是“view的控制器、管理器”,所以VC能管理view的生命周期,所以我们在VC里写业务会更方便开发!

说了那么多,我就想说明一个观点:

在一个VC里(主页面),要另开一个VC(侧滑菜单页面),那就创建一个嘛,然后把侧滑页面的view addSubview到主页面里不就完事了?

好了,业务与页面都被抽象到另一个VC了(当然了你要自定义一个侧滑菜单VC)。那么主页面的VC和侧滑菜单页面的VC已经逻辑分离,耦合松散了。只不过,主页面此时还必须知道有“侧滑页面”这个VC的存在。

4. 进一步解耦合

在第3点中,我们已经初步解耦合了,但是是不是有更优雅的方式?

回想NavigationController,这个控制器存在的意义是什么?它可以将两个VC进一步解耦合。

这个进一步解耦合是如何体现的呢?回想第3点,我们已经做到了将两块业务分散到了两个VC中,但是,view还是完全耦合在一起的,因为主页面的view和侧滑菜单页面的view是通过addSubview的方式进行关联的。而NaviagtionController就是进一步将view解耦,通过NavigationController.view。

每个导航栏都有自己的view,上面只有一个NavigationBar视图,下方是空视图,第一个VC的view是addSubview到导航栏的view上面的。然后我们push了第二个VC,那么第二个VC的view此时就不是直接addSubview到第一个VC的view上去的,而是add到NavigationController.view上去的,然后伴随推入的动画将第二个VC的view进行显示。此时第一个VC的view和第二个VC的view,不在是“父子”关系,而是“兄弟”关系了。

能理解这层解耦合关系吧?那么我们来说说我们的侧滑菜单如何解耦合。

5. 侧滑菜单如何解耦合—控制器转场

这里不细说控制器转场如何实现,想学习的google一堆。这里想说的是转场究竟是个什么东西。

控制器转场就是通过一系列动画,操作两个VC的view进行切换显示。切换显示的时候,会有两个VC的父view:containerView,然后两个VC的view在上面add、remove,再加点动画,就可以了。

无论是push还是present,都是转场,就是操作view的addSubview或者removeFromSuperview

一是给两个VC解耦,二是做动画,用户体验更友好。

控制器转场的本质就是view做动画,操作view,和你的VC没有太大关系

明白这个道理后,熟练使用各种动画技能的你就可以在转场中行云流水了。

等等,侧滑可是两个界面同时显示啊!你说你都能控制两个view了,你难道不能控制view的frame,不能控制view的大小,不能控制两个view怎么叠加怎么摆放?不要被VC传统的用法束缚,在这里,view才是你的主角。

轻总结

新手往往被苹果指定的用法所束缚(如VC和view的关系),那是因为没有清楚理解苹果提供的“用法”的本质。当然,苹果的用法已经足够优秀,你不必考虑部分细节也能进行使用,但是,理解“用法”的本质,才能让你走的更远。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,565评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,021评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,003评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,015评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,020评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,856评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,178评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,824评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,264评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,788评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,913评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,535评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,130评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,102评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,334评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,298评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,622评论 2 343

推荐阅读更多精彩内容