UIViewController和UIViewController之间的交互

UIViewController和UIViewController之间的交互,第1张

概述转载时请注明出处和作者联系方式 文章出处:http://blog.csdn.net/jack0106  作者联系方式:冯牮 fengjian0106@yahoo.com.cn        UIViewController之间,是否需要交互,怎样交互?这个问题困扰我一段时间了,凭空的去想象,其实很难想明白,尤其是在短时间内。最好的办法,还是在持久的编码/读代码的过程中,根据不同的使用场合及使用需求 转载时请注明出处和作者联系方式

文章出处:http://blog.csdn.net/jack0106 

作者联系方式:冯牮 fengjian0106@yahoo.com.cn


       UIVIEwController之间,是否需要交互,怎样交互?这个问题困扰我一段时间了,凭空的去想象,其实很难想明白,尤其是在短时间内。最好的办法,还是在持久的编码/读代码的过程中,根据不同的使用场合及使用需求,来学习体会。


       顺便还想说一句,图形界面编程,最基本的编程思路和方法都是类似的,如果你熟悉不止一种图形SDK,你就会发现其实它们都是触类旁通的。最近我就游走于cocoa和qml之间,再加上之前qtWidget、gtk、clutter的编程经验,我发现使用这些不同的sdk,对于我个人的编程技能的增长,很好的起到了互补的作用。


       假设使用UINavigationController进行导航,有两层界面结构,都使用自定义UIVIEwController的子类,分别为level1VIEwController和level2VIEwController。

 

1 单向交互。

       第一级level1VIEwController负责创建第二级level2VIEwController,并且设置level2VIEwController相关的属性,然后push level2VIEwController。伪代码如下:

[plain] view plain copy print ? [[level2VIEwController alloc] init];       [level2VIEwController setProp_1];   [level2VIEwController setProp_2];   [level2VIEwController setProp_3];       [level1VIEwController. navigationController   pushVIEwController:level2VIEwController];       [level2VIEwController release];  

       这种情况下,从level1VIEwController的角度来看,它只需要初始化level2VIEwController,设置它的一些属性,调用push,然后就什么都不用管了。从level2VIEwController的角度来看,当它被push后,在它的生命期内,都不会影响level1VIEwController,不需要调用level1VIEwController的函数,也没有事件需要通知level1VIEwController。

 

       这是最简单的使用情形,也是最理想化的。在项目设计阶段,应该尽量把代码设计成这种结构(仅仅是尽量,并不是必须。而且,也并不是所有的使用场景都都可以设计成这样的结构,毕竟这个太理想化了)。

 

2 双向交互,共享数据

       level1VIEwController和level2VIEwController使用共同的一个数据shareData(一定要理解这里“共同”的含义------两个controller共享同一个数据,并且都有可能进行读写 *** 作,尤其是写 *** 作。如果level2VIEwController只对数据进行读 *** 作,那其实就跟前面1中的情形是一致的)。第一级level1VIEwController负责创建第二级level2VIEwController,并且设置level2VIEwController相关的属性,同时还要把shareData传递给level2VIEwController,然后push level2VIEwController。伪代码如下:

[plain] view plain copy print ? <span ></span><pre name="code" >[[shareData alloc] init];   …   [[level2VIEwController alloc] init];       [level2VIEwController setProp_1];   [level2VIEwController setProp_2];   [level2VIEwController setData: shareData];       [level1VIEwController. navigationController   pushVIEwController:level2VIEwController];       [level2VIEwController release];  

@H_236_301@ 

        和前一种情形的区别是,在level2VIEwController的生命期内,它可能会对shareData进行写 *** 作,当发生这种写 *** 作的时候,需要让level1VIEwController知道这种变化,并且作出对应的处理。

 

        这个时候,比较容易想到的一种解决办法是使用Delegate,当level2VIEwController写 *** 作shareData时,通过Delegate机制通知level1VIEwController,给予level1VIEwController一个机会作出正确的响应。

 

        这种办法虽然可行,但并不是首选,在面向对象编程中,经常会提到“解耦”,这里我们就要想办法让这两个controller不要联系的这么紧密。那么怎么办呢?

就是使用MVC模式(UIVIEwController本身就是MVC中的C)。这个时候,shareData就不应该再是一个普通的数据,而应该封装成model,当model中的数据发生了改变的时候,会发出通知告诉C(和/或 V)。这样的话,两个controller之间就比较松散了。引入dataModel后,伪代码如下:

[plain] view plain copy print ? <span ></span><pre name="code" >[[shareData alloc] init];   [dataModel alloc] initWithData: shareData];   …   [[level2VIEwController alloc] init];       [level2VIEwController setProp_1];   [level2VIEwController setProp_2];   [level2VIEwController setModel: dataModel];       [level1VIEwController. navigationController   pushVIEwController:level2VIEwController];       [level2VIEwController release];  
@H_236_301@   

       当level2VIEwController修改shareData后,不需要负责通知level1VIEwController。shareData会负责通知它的controller。

 

 

3 双向交互,逆向消息传递

       这时,基本 *** 作都还是前面描述的1或2中的情形,区别点在于,在level2VIEwController的生命期内,发生了某个事件,需要让level1VIEwController知道这个事件,并且作出对应的处理。

 

       这个时候,就只能用Delegate了。当level2VIEwController发生某个事件时,通过Delegate机制通知level1VIEwController,给与level1VIEwController一个机会作出正确的响应。

 

       但是!一定要谨慎使用这种方案。如果发现代码中需要用到这种结构,首先应该重新审视项目的架构,看能不能用前面两种方案来处理,可能需要做一定的代码重构。当前面的方案实在是无能为力的时候,才考虑使用此方案。而且,尽量让这种逆向的消息传递更简单,消息事件不要太多。

 

4 双向交互,大量逆向消息传递

       这种情形和前面的3是一样的,但是level2VIEwController和level1VIEwController之间的消息传递更复杂。

 

       这个时候,同样,要审视代码的结构是否合理。而且很大的可能性是设计不合理,应该考虑把level2VIEwController中管理的UIVIEw迁移到level1VIEwController中,把controller之间的交互,变成controller内部的vIEw之间的交互,让level1VIEwController的内部聚合的更紧密一些,对外部,level1VIEwController则表现的更松散。例如,UIAlertVIEw或UIActionSheet,都是UIVIEw的子类。(此处并不绝对,在有些sdk中,类似于UIAlertVIEw或UIActionSheet的组件,它的使用情形,是符合前面3中的描述的,因为这两种组件的行为模式,是有规律性的,可以很方便的复用,举个例子,桌面编程环境中,文件选择器这种组件,通常就是一个顶层window)

 

 

最后还要补充说明一些内容。

        Cocoa是比较严格的执行了MVC设计模式,其中的UIVIEwController,可以看成是某种使用场合下,一些内在联系很紧密、并且协同工作的UIVIEw的一个顶层管理容器。

 

        在其他的sdk中,不一定有严格的controller,很有可能只有M和V(C的功能在V内实现),甚至只有V(简单的使用场景,就可以不区分M和C,全在V内管理)。这个时候,就有顶层VIEw的概念(有很多种叫法,比如page、window,或者直接使用abstractWidget),这种逻辑概念上的顶层VIEw,在设计的时候,同样需要考虑它们之间的交互,前面描述的这些情形,同样可以套用。

 

        在用户体验的角度来看,controll或者顶层vIEw,通常被成为“场景”,场景之间是否需要交互,前面的描述,也有一定的参考价值。

 

        但是场景的概念并非总和controll或顶层vIEw严格对应,“场景”是更抽象化的内容,更符合人类的直观感觉,而controll/顶层vIEw是更工程化的概念,更精确。在用户体验设计中,有些不同的场景,在逻辑上其实可以属于同一个controll或顶层vIEw。这个随着经验的增长,体会才能够更加的深刻。

 

        关于用户体验设计中的场景,推荐一片文章,可以看看其中举的一些例子,找找感觉。

        不拘规范的iPhone优秀应用设计细节     http://ucdchina.com/snap/10799

总结

以上是内存溢出为你收集整理的UIViewController和UIViewController之间的交互全部内容,希望文章能够帮你解决UIViewController和UIViewController之间的交互所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1058475.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存