V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
James369
V2EX  ›  iDev

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

  •  
  •   James369 · 2021-10-13 07:19:24 +08:00 · 5806 次点击
    这是一个创建于 1139 天前的主题,其中的信息可能已经有所发展或是发生改变。
    为了更好的复用同一种类型的对象,避免出现冗余出多份代码,有的时候就会需要对 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. 通过一种代码结构 /设计模式来实现?
    第 1 条附言  ·  2021-10-13 11:58:13 +08:00
    本意我还是想能够从 xib 的 file owner 入手简单的处理(似乎 XCode 并不支持,我认为是苹果的锅)。
    现在竟然不行,那我还是直接复制一份 xib 出来,可能还更快。
    谢谢各位。
    第 2 条附言  ·  2021-10-17 10:14:19 +08:00
    并不是苹果的锅,后来从 Nib/Bundle 编程手册中找到了一些线索,loadNibNamed(_:owner:options:)方法应该可以解决多对一的问题,也体会了 Xib 的强大。
    16 条回复    2021-10-15 20:47:45 +08:00
    nieyujiang
        1
    nieyujiang  
       2021-10-13 07:37:19 +08:00
    国内一般都不怎么用 xib 把.都是直接代码写
    Building
        2
    Building  
       2021-10-13 08:08:37 +08:00 via iPhone
    数据和 UI 为什么要绑在一起?操作可以交给指定代理处理。
    qq73666
        3
    qq73666  
       2021-10-13 08:47:25 +08:00
    纯代码呗,xib 复用性不足
    James369
        4
    James369  
    OP
       2021-10-13 08:52:02 +08:00
    @Building 我来想到例子,一个 xib 页面可以用于不同的 2 控制器:比如房屋求租信息和出租信息,求租和出租是 2 套不同的模型(具体目前是放在 2 个不同的 ViewController 中),但是它们的界面可以是完全一模一样。
    linKnowEasy
        5
    linKnowEasy  
       2021-10-13 09:30:27 +08:00
    @James369 #4 这种场景. 用代码写. 复用不是更简单嘛?
    如果非用 n 个 Class 对应 1 个 xib , 我的想法是用一个 base . n 个 Class 都继承 这个 base , 不知道可行不
    mcluyu
        6
    mcluyu  
       2021-10-13 09:32:17 +08:00
    换个思路, 为什么不用两个数据源而要用两个 controller
    CommandZi
        7
    CommandZi  
       2021-10-13 09:36:12 +08:00
    是可以的,但是不建议
    divilkcvf
        8
    divilkcvf  
       2021-10-13 09:45:58 +08:00
    xib 是父类,直接继承出两个子类,在子类上修改不就行了吗?
    James369
        9
    James369  
    OP
       2021-10-13 09:55:47 +08:00
    @linKnowEasy
    @divilkcvf
    你们提的这种方法理论上可行性很高,即通过一个基类去绑定 xib 。
    不过本质上的问题是 2 套数据模型要与 1 个 xib 绑定(也就是 2 套数据模型要去操作 Xib 的 outlet 界面元素)。也就是在这个基类中,要把所有 outlet 界面的操作全部封装出来,然后给 2 个不同的子类去调用。(改动还是不少)
    linKnowEasy
        10
    linKnowEasy  
       2021-10-13 10:03:27 +08:00   ❤️ 1
    @James369 #9 你这个如果要省略 `操作全部封装出来` 的话. 那直接在基类的声明方法. 子类 覆盖重载
    James369
        11
    James369  
    OP
       2021-10-13 10:11:10 +08:00
    @linKnowEasy 其实我还是想能够从 xib 的 file owner 入手简单的处理。 不过这也算是一个不错的方案。
    alvinbone88
        12
    alvinbone88  
       2021-10-13 10:31:59 +08:00
    把界面单独抽出来做成一个 view,然后由不同的 ViewController 加载就行了
    如果还有共同的逻辑,就封装成 ViewController,其他 ViewController 可以通过 addChildViewController 来加载,自定义的逻辑可以通过 block 传递
    James369
        13
    James369  
    OP
       2021-10-13 10:36:49 +08:00
    @alvinbone88 这可是一个大 view,那么 xib 中的那些 outlet 怎么进行关联呢?
    wangkun2012324
        14
    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
        15
    divilkcvf  
       2021-10-13 11:18:26 +08:00
    @James369 那就不要使用继承,通过 addsubview 的方式在两个不同的 view 里加入 xib 作为子 view,xib 的 viewcontroller 再开通不同的接口让这两个不同的 view 进行自定义
    BB9z
        16
    BB9z  
       2021-10-15 20:47:45 +08:00
    情形 2 可以理解为 N 个界面同一个展现。这种情况我会在 storyboard 中定一个展现 vc,在其他业务 vc 中嵌入之。比如社交应用的用户列表,关注用户、我的好友、用户搜索等各种业务,嵌入一个公共的用户列表展现层就好,像接口、是否有增删功能等作为参数传进去即可。我自己的项目框架指定个接口直接在 storyboard 设置一行属性就可以了。

    View 级别外观复用,xib ;
    页面 / View 级别外观复用,嵌入 storyboard 中其他 vc ;
    View 级别逻辑复用,定义单元 view,在各种 cell 、vc 中嵌入;
    页面级别逻辑复用,协议扩展、继承。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5537 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 09:29 · PVG 17:29 · LAX 01:29 · JFK 04:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.