【问题标题】:How to differentiate iOS UIKit dataSource and delegate methods for multiple objects in the same UIViewController?如何区分同一 UIViewController 中多个对象的 iOS UIKit 数据源和委托方法?
【发布时间】:2014-10-16 11:45:09
【问题描述】:

我注意到在使用 UITableView、UICollectionView、UIPickerView、UIScrollView、...以及许多其他 UIKit 类时,包含对象实例的 UIViewController 通常承担着 DataSource 和 Delegate 的角色。

我从 Apple 的文档中了解到这些数据源和委托方法被称为什么,以及如何实现它们……对于每个类的单个实例。

我的问题是,你如何处理同一个 UIViewController 中的不同实例?例如,如果我有两个 UICollectionViews,或者三个 UIPickerViews,......,还是五十个 UIScrollViews?每个 UIViewController 只能实现一次数据源方法,但我必须以某种方式告诉程序不同的指令?

我唯一能想到的是一个巨大的 switch 语句或一堆级联 if-else if-else 将委托或数据源方法的输入与 UIViewController 中的每个对象实例进行比较,如果有很多。

【问题讨论】:

  • @Christian:题外话。是的,正如我在原帖中提到的,我知道第一个参数是调用者,但这会导致长级联 if 比较或 switch 语句,通常不是解决编程问题的好方法。有没有更聪明的方法?
  • @Kampai:并非不可能。显然,不同的 UICollections 显示不同的集合。例如,两个用户的照片集。如果每个人都只需要一个 UICollectionView,你认为 Apple 为什么将它与 UICollectionViewController 分开?别再这么自以为是了,继续关注主题。
  • @Simon McLoughlin:我不需要两个 VC 课程。我有一个 VC,只是同一个类的多个项目调用同一个委托方法。
  • @Cindeselia 抱歉,我误解了您的问题。正如其他人所提到的,每个委托都会触发对创建它的元素的引用。你可以用它来比较
  • @Cindeselia 我不明白,为什么我的评论跑题了。不过,您可以将委托代码提取到外部类,并为每个 UIView 分配另一个委托。这样您就可以保持 VC 的代码干净。

标签: ios objective-c iphone uiviewcontroller uikit


【解决方案1】:

虽然我们习惯于使用我们的视图控制器作为委托,但没有必要这样做。您实际上可以创建符合相关委托协议的NSObject 子类。然后,您可以实例化这些对象并根据需要将它们用作 UI 对象(或其他对象)的代表。

例如,考虑一个场景,我有两个文本字段,一个只允许数值,一个不接受数值。我可以为每种类型的文本字段编写一个单独的委托对象。

    1234563 .
  1. 如果在 Interface Builder 中执行此操作,您实际上可以将“对象”从“对象库”拖到场景中(在场景上方的栏中或场景左侧的文档大纲中):

    然后您可以指定该对象的类:

    对所有委托对象重复此操作:

    最后,您可以转到您的文本字段并通过控制拖动到您添加到场景中的委托对象来指定委托:

    在 Interface Builder 中执行此操作意味着它完全为我处理了此委托对象的实例化,而我无需在视图控制器的代码中执行任何操作。

归根结底,如果您希望 UI 对象具有不同的行为,您可以只实例化一个单独的委托对象以显示所需的行为,并将其用作 UI 对象的委托。这种实例化单独委托对象的模式在 iOS 7 自定义转换中很常见(我们有各种各样的委托对象),但也可以在这种情况下使用。

顺便说一句,您显然也可以将相关的 UI 控件子类化,并进一步封装那里的逻辑。这同样有效。

【讨论】:

    【解决方案2】:

    通过为每个控制器创建引用插座,例如,如果您有两个 UITableView ,您可以为每个控制器创建插座,例如 table1 和 table2。要为这些表设置一个部分中的行数,您可以编写如下代码

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
    
        if (tableView == table1) {
            return 10;
        }
    
        if (tableView == table2) {
            return 5;
        }
        return 1;
    }
    

    【讨论】:

    • 谢谢,但我在原始帖子中提到了这种可能性。有什么更好的方法?详尽地列出 50 个或许多比较似乎并不是一个好的可扩展解决方案......
    【解决方案3】:

    您可以使用自己的 .swift 和 .xib 为每个 tableView 或集合视图创建独立的 UIView(如果它们非常相似,您可以重复使用它们)。这样做,您将在单独的文件中拥有 tableView 和 collecionView 委托方法,一切都会更加清晰。在您的视图控制器中,您只需要放置视图,但不会有任何委托方法。

    【讨论】:

      【解决方案4】:

      嗯,您要求以更智能的方式区分视图与数据源和委托。但是你在这件事上想多了。

      1. 每个人都采用不同的表格视图或选择器,因为它们不一样。 否则它们可以重复使用。

      2. 现在,如果他们要与其他人不同,那么最终您必须在代码中的某个位置放置 if...else 或 case 语句。例如,在设置 UILabel 的值或 UITableViewCell 中的任何值时用于 tableview。

      3. 如果您面临这样一个问题,您必须在一个 UIViewController 中放置这么多滚动视图或其他内容,那么如果您遵循编码标准或者您的应用程序设计有问题,这是不可能的情况.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-07
        • 1970-01-01
        • 1970-01-01
        • 2012-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多