Swift SB 容器 Container View使用

最近比较清闲,就把以前学习的过程记录下吧,多少年后如果能在互联网上找到自己的痕迹,想想还是一件蛮值得高兴的事情

容器在开发过程中用到的地方还是蛮多的,像网易新闻的框架如果使用代码去实现的话,调用系统的API

addChildViewController(<#T##childController: UIViewController##UIViewController#>)

使它成为子控制器,加入一个类似的容器里面就可以,具体的大家在做项目过程中都用到过,这里就不多说了。今天就分享一下SB上使用容器类管理VC的控件ContainerView(纯代码里没有这个控件)

新建个项目(这里我使用的是以前自己随便写的一个小demo),在Manstoryboard 的 view 上拖拽两个ContainerView ,给他们两个分别设置约束,宽度加起来等于屏幕宽度就可以。拖拽完后你会发现view上多出来两根线并且关联到两个VC。其实这就是containerView 自带的容器VC,它让我们可以把代码和业务都分发到一个独立的VC里面去操作,耦合性更低。

F9020D89-DD10-499B-867C-EAEB671EA94C.png

为了后面的操作我们需要在swift文件里面给这两个VC绑定两个Class,取名为Class1 和Class2 都继承于BaseVC(BaseVC里面只是简单的对导航栏里面的操作) 。然后要将ContainerView关联的VC跟我们swift文件里面的类关联起来,并且绑定它们的storyboardId


496E928E-DF3D-4EEF-8AB3-5E00B88C88E4.png

到现在的话,基本上容器的使用算是完成了,我们想做的业务就可以分别在两个vc里面实现了。但是这样的话就太不直观了,接着说个例子吧。

现在好多App 都有双列表,比方说京东的

E9CF7C2DEB41E4D5ABE42757F3743A19.png

这个双列表页面,我们就能使用ContainerView 来实现类似的效果。

首先我们在Class1 和Class2 里面各自添加两个tableView 并给他们附上数据,最终的效果是这样的

4111837F-1E2A-4BC2-9907-C5689457B970.png

这个时候如果我们想做数据的交互,就需要传值。OC里面的传值方式有很多,通知,代理,block 等等,其实最简单的就是使用NSNotificationCenter ,通知比较简单,我就不说了,swift里面的使用跟OC差不多。这里说一下代理的用法和swift里面闭包的用法

代理在这里的用法

先说下代理,因为我们使用的是容器ContainerView 它会自带两个VC,又加上原来的一个VC,相当于三个VC,怎么ContainerView里面取到对应关联的两个VC,这是一个关键。

在承载连个ContainerView 的VC里面重写下面的方法

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
    }

只需要重写系统的这个方法,这个方法是SB里面的视图切换的时候系统会调用的一个方法,它的参数 segue.destination

let vc = segue.destination

返回的就是对应的ContainerView 自带的VC

E7476A3F-5AAC-4209-924B-4D9F3EA52CC1.png

因为我们使用了两个VC 所以要判断下是具体哪个VC

    var class1:Class1? = nil
    var class2:Class2? = nil
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? Class1 {
            class1 = vc
        }
        if let vc = segue.destination as? Class2 {
            class2 = vc
        }
    }

取到这两个VC后,就好办多了。然后要做的无非就是声明协议,遵循代理,实现代理方法

protocol XWContainerViewResponseDelegate {
    func clickWithGetIndex(index:NSIndexPath)
}

声明一个协议,参数为NSIndexPath 类型,然后让Class1 声明一个代理属性

    var delegate:XWContainerViewResponseDelegate?

然后在Class1 tabviewVIew 的点击方法里面调用代理(不需要去调用responds(to: <#T##Selector!#>) delegate? 就相当于OC里面的responds)

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
       delegate?.clickWithGetIndex(index: (indexPath as? NSIndexPath)!)
   }

然后让Class2 去遵循协议,实现代理方法,这样就OK了。但是不知道大家有没有发现,OC使用的时候我们一般都会设置

XXXX.delegate = XXXX

这一步我们还没有写,但是这Class1 和 Class2 又是独立的,没有关联。所以这个时候我们就要用到承载这两个容器所在的VC了,在上面的那个方法里面,我们获取到了这两个VC,在这里进行关联

    var class1:Class1? = nil
    var class2:Class2? = nil
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? Class1 {
            class1 = vc
        }
        if let vc = segue.destination as? Class2 {
            class2 = vc
        }
        class1?.delegate = class2
    }

OK,这样就完整了,点击Class1 的cell 就会把对应的IndexPath 传过去,就可以做操作了

闭包在这里的用法

在说下使用闭包传值的做法
其实核心的地方都在承载两个ContainerView 所在的VC里面。因为我们所做的操作是想点击Class1 里面的cell,把对方的Indexpath 给传过去,那么肯定是想把IndexPath 给回调出去。回调出去之后Class2 怎么去接受呢?其实Class2 也可以有一个闭包专门去接受这个数据,但是这样就太麻烦了。我们可以在Class2 里面声明一个属性,去实现它的属性观察器方法,这样就能随时监听这个属性的变化,更方便的去做操作

首先在class1 里面去声明闭包,顺便给它一个属性去记录所要传递的IndexPath

    typealias CallBack = (_ index:NSIndexPath)->Void
    var xwCallBack:CallBack?
    var class1Index: NSIndexPath? = nil

Class2 里面的操作 声明属性观察器

 var class2Index:NSIndexPath? = nil {
        willSet {
            
        }
        didSet {
            print("得到的从1传过来的值  \(String(describing: class2Index?.row))")
        }
    }

然后在Class1 cell的点击方法里面去调用它

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        xwCallBack!(indexPath as NSIndexPath)   
    }

ContainerView 承载所在的VC 让Class1 实现闭包

 var class1:Class1? = nil
    var class2:Class2? = nil
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? Class1 {
            class1 = vc
        }
        if let vc = segue.destination as? Class2 {
            class2 = vc
        }
        
        unowned let weakSelf = self
        class1?.xwCallBack = { index in
            weakSelf.class2?.class2Index = index
        }
    }

然后把Class1传过来的IndexPath 赋值给Class2的 带有属性观察器的属性。OK,这样就可以了

其实swift 里面的东西 大致跟OC用法还是一样的,只不过增加了一些确实特别好用的东西。无论什么方法,用到好就行。黑猫白猫,逮到老鼠就是好猫

一起学习吧。。。

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

推荐阅读更多精彩内容

  • 前言的前言 唐巧前辈在微信公众号「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各项指标...
    VincentHK阅读 5,335评论 3 44
  • 主要内容:实现自定义转场动画 大家平常用微信,微博的过程中肯定都有查看过朋友圈和微博所发布的照片,当点击九宫格的某...
    DHai阅读 1,138评论 1 1
  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,160评论 1 23
  • 1.badgeVaule气泡提示 2.git终端命令方法> pwd查看全部 >cd>ls >之后桌面找到文件夹内容...
    i得深刻方得S阅读 4,628评论 1 9
  • “神不贪,为何容不得一点对其不敬?神不恶,为何要将地上千万生灵命运,握于手中?” 从《西游记》开始,到《大话西...
    皮吃皮吃阅读 331评论 0 3