【问题标题】:Common View Controller Base Class公共视图控制器基类
【发布时间】:2012-07-23 10:00:48
【问题描述】:

我想为我的项目创建一个BaseViewController 类(继承自UIViewController),它可以作为我项目中其他视图控制器的基类。这是为了添加一些东西,例如一个常见的进度 HUD、一个刷新按钮和网络更新机制,也许是一个可以由每个子类自定义文本的错误对话框等。

至关重要的是,我希望能够将此功能添加到 UIViewController 子类和 UITableViewController 子类中,但我无法将自己插入到 UITableViewController 类层次结构中,因此实际上我需要一个 BaseUIViewControllerBaseUITableViewController,但如果我这样做,我必须实施两次更改并保持同步。

BaseViewController 子类和BaseTableViewController 子类都可以访问的公共代码提供一个单一位置的最佳方法是什么?我只希望我的代码中有一个地方可以用来处理常见任务。

1) 我考虑过使用associative references 的类别,但这里的问题是我需要自定义实现 ViewController 生命周期类,例如 viewDidLoad:,这不是一个好主意。

2) 我可以完全跳过 UITableViewController,并从 BaseViewController 构建我自己的 BaseTableViewController,自己实现 tableView delegatedatasource 方法,但我不太想跳过苹果的控制器在这里实现。

3) 我可以有一个从UIViewController 继承的BaseViewController,从UITableViewController 继承的BaseTableViewController,只需将自定义方法调用放入第三个文件ViewControllerBaseMethods 即可从两个“基本”文件中调用.可能仍然存在重复的属性,但至少方法代码会在一个地方。

对于这类事情还有其他好的方法吗?

【问题讨论】:

    标签: objective-c ios uiviewcontroller


    【解决方案1】:

    UITableViewController 所做的只是提供一个 UITableView 属性,将自己声明为委托和数据源,并将其视图设置为表格视图

    所以创建一个扩展 BaseViewController 的 BaseTableViewController,将其声明为 UITableViewDataSource 和 UITableViewDelegate 并实现所需的方法,添加 UITableView 属性并实现 loadView:

    - (void)loadView
    {
        self.tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] andStyle:UITableViewStylePlain];
        self.tableView.delegate = self;
        self.tableView.datasource = self;
        self.view = self.tableView;
    }
    

    如果你想使用不同的表格视图样式,你可以提供一个通用的方法或属性来在初始化时获取表格视图样式

    【讨论】:

    • 我能想到的唯一好处是在使用 Xcode 模板时为 cellForRow、didSelect 等获取代码 sn-ps。但更少的代码重复弥补了这一点
    • 对,听起来像滚动我自己的 UITableViewController 替换继承基础 UIViewController 是最明智的方法。
    • UITableViewController 做了很多事情。例如,键盘显示时自动调整位置,ContentInsets 自动调整
    • “UITableViewController 所做的只是提供一个 UITableView 属性”——这不再是真的了。它还提供了 UIRefreshControl 等其他功能。
    • UITableViewController 如果要使用静态表格视图,则需要。
    【解决方案2】:

    我认为,您应该使用您的公共属性和功能创建一个协议定义,并且您的 BaseTableViewController 和 BaseViewController 必须采用它。之后,您的第三个选项听起来不错,您应该创建一个包含协议实现的文件 (ViewControllerBaseMethods),该文件应该从两个“Base”文件中调用。

    因此方法代码将在一个地方,并且没有多个属性声明。

    这是解决 Objective-C 中缺少多重继承的方法。

    【讨论】:

    • 谢谢。是的 - 缺乏多重继承实际上是问题所在,因此使用协议(而不是我建议的选项 2.,在这种特殊情况下我可能能够摆脱)有一个通用的答案非常有帮助。
    • @ingaham 你能举个例子吗?
    【解决方案3】:

    在 Swift 中,您可以创建一个 UIViewController 扩展并将您的方法放在那里,这样您就可以在 UIViewControllers 和 UITableViewControllers 中使用它们。

    extension UIViewController {
        var aComputedProperty: Bool {
            return true
        }
    
        func aMethod() {
            //do something
        }
    }
    

    这样做的缺点是您将无法使用存储的属性。

    var aProperty: Int? //this is not allowed in extensions
    

    【讨论】:

      猜你喜欢
      • 2017-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 2016-01-13
      • 1970-01-01
      • 1970-01-01
      • 2016-01-18
      相关资源
      最近更新 更多