如何建立 Class 与 Xib/Storyboard 之间的一对多/多对一的关系?

2021-10-13 07:19:24 +08:00
 James369
为了更好的复用同一种类型的对象,避免出现冗余出多份代码,有的时候就会需要对 Class 对象与 Xib 对象之间建立 1:n 或 n:1 的关系。

情形 1. 1 个 Class 对应 n 个 xib:比如常见的电商 App 的商品列表页面,可以呈现为列表模式或网格模式,这种就是一个 ViewController 通过创建不同的 Cell 的 Xib 来实现。

情形 2. n 个 Class 对应 1 个 xib:最近我就碰到这种需求,但不知道如何好的做? 2 个不同的 ViewController,界面长得完全一样(可以共用 1 个 xib ),只不过 2 个 ViewController 操作的数据不一样(数据操作代码分布在 ViewController 文件的多个地方),目前想到 2 想法:
1. 能否在 1 个 xib 中指定多个不同的 File Owner 来实现,要是可以这种比较简单直接。
2. 通过一种代码结构 /设计模式来实现?
5832 次点击
所在节点    iDev
16 条回复
nieyujiang
2021-10-13 07:37:19 +08:00
国内一般都不怎么用 xib 把.都是直接代码写
Building
2021-10-13 08:08:37 +08:00
数据和 UI 为什么要绑在一起?操作可以交给指定代理处理。
qq73666
2021-10-13 08:47:25 +08:00
纯代码呗,xib 复用性不足
James369
2021-10-13 08:52:02 +08:00
@Building 我来想到例子,一个 xib 页面可以用于不同的 2 控制器:比如房屋求租信息和出租信息,求租和出租是 2 套不同的模型(具体目前是放在 2 个不同的 ViewController 中),但是它们的界面可以是完全一模一样。
linKnowEasy
2021-10-13 09:30:27 +08:00
@James369 #4 这种场景. 用代码写. 复用不是更简单嘛?
如果非用 n 个 Class 对应 1 个 xib , 我的想法是用一个 base . n 个 Class 都继承 这个 base , 不知道可行不
mcluyu
2021-10-13 09:32:17 +08:00
换个思路, 为什么不用两个数据源而要用两个 controller
CommandZi
2021-10-13 09:36:12 +08:00
是可以的,但是不建议
divilkcvf
2021-10-13 09:45:58 +08:00
xib 是父类,直接继承出两个子类,在子类上修改不就行了吗?
James369
2021-10-13 09:55:47 +08:00
@linKnowEasy
@divilkcvf
你们提的这种方法理论上可行性很高,即通过一个基类去绑定 xib 。
不过本质上的问题是 2 套数据模型要与 1 个 xib 绑定(也就是 2 套数据模型要去操作 Xib 的 outlet 界面元素)。也就是在这个基类中,要把所有 outlet 界面的操作全部封装出来,然后给 2 个不同的子类去调用。(改动还是不少)
linKnowEasy
2021-10-13 10:03:27 +08:00
@James369 #9 你这个如果要省略 `操作全部封装出来` 的话. 那直接在基类的声明方法. 子类 覆盖重载
James369
2021-10-13 10:11:10 +08:00
@linKnowEasy 其实我还是想能够从 xib 的 file owner 入手简单的处理。 不过这也算是一个不错的方案。
alvinbone88
2021-10-13 10:31:59 +08:00
把界面单独抽出来做成一个 view,然后由不同的 ViewController 加载就行了
如果还有共同的逻辑,就封装成 ViewController,其他 ViewController 可以通过 addChildViewController 来加载,自定义的逻辑可以通过 block 传递
James369
2021-10-13 10:36:49 +08:00
@alvinbone88 这可是一个大 view,那么 xib 中的那些 outlet 怎么进行关联呢?
wangkun2012324
2021-10-13 11:08:39 +08:00
情形 1,不存在一对多关系,多种 cell 对多个 xib 就是,和 viewcontroller 没有关系
情形 2,如果用 Xib/SB 这种想复用,那么必然细化,如果你的 ViewController Class 持有了各种逻辑,那么要么使用继承 xib 对应 一个 FatherViewController,两个子 viewController,要么直接 Xib 只对应 View,两个 viewController load 同一个 View
divilkcvf
2021-10-13 11:18:26 +08:00
@James369 那就不要使用继承,通过 addsubview 的方式在两个不同的 view 里加入 xib 作为子 view,xib 的 viewcontroller 再开通不同的接口让这两个不同的 view 进行自定义
BB9z
2021-10-15 20:47:45 +08:00
情形 2 可以理解为 N 个界面同一个展现。这种情况我会在 storyboard 中定一个展现 vc,在其他业务 vc 中嵌入之。比如社交应用的用户列表,关注用户、我的好友、用户搜索等各种业务,嵌入一个公共的用户列表展现层就好,像接口、是否有增删功能等作为参数传进去即可。我自己的项目框架指定个接口直接在 storyboard 设置一行属性就可以了。

View 级别外观复用,xib ;
页面 / View 级别外观复用,嵌入 storyboard 中其他 vc ;
View 级别逻辑复用,定义单元 view,在各种 cell 、vc 中嵌入;
页面级别逻辑复用,协议扩展、继承。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/807443

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX