如何创建基本视图控制器

时间:2015-11-19 16:49:34

标签: ios iphone swift uiviewcontroller

我希望BaseViewController子类UIViewController覆盖其中一个方法,但也需要它的子类来实现新方法。

我的情况有点复杂,但这个简单的案例代表了我的问题:

我的BaseViewController会覆盖viewWillAppear来设置它的标题,但标题字符串会来自它的子类。我想到了一些选择,不确定是否/哪一个最好。

1 - 具有错误抛出方法的类(我当前的解决方案):

class BaseViewController: UIViewController {
  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    title = getTitle()
  }

  func getTitle() -> String {
    fatalError("Unimplemented method")
  }
}

2 - 在构造函数中接收标题:

class BaseViewController: UIViewController {
  var myTitle: String!

  convenience init(title titleSent: String) {
    self.init(nibName: nil, bundle: nil)
    myTitle = sentTitle
  }

  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    title = myTitle
  }
}

请注意,如果要发送更多参数,此选项会非常糟糕

我认为使用protocol是完美的,直到我发现(当然)协议不能对一个类进行子类化。

以前没有人这样做过吗?我不这么认为,请分享你的想法。

更新

我尝试了另一种方法,但是遇到了编译错误,这会不会有效?

procotol BaseViewController {
  var myTitle: String { get }
}

extension BaseViewController where Self: UIViewController {
  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    title = myTitle
  }
}

编译器说Method does not override any method from its superclass

1 个答案:

答案 0 :(得分:6)

我通常创建协议,在其中声明控制器中的内容。然后我检查基本控制器是否实际实现,如果是,只需使用值,如下所示:

protocol ControllerType {
    var navigationTitle: String { get }
}

extension ControllerType {
    var navigationTitle: String {
        return "Default title"
    }
}

class BaseViewController: UIViewController {

    override func viewDidLoad() {
        if let controller = self as? ControllerType {
            self.title = controller.navigationTitle
        }
    }
}

class ViewController: BaseViewController, ControllerType {

    var navigationTitle: String {
        return "ViewController"
    }

    override func viewDidLoad() {
        super.viewDidLoad()    
    }
}

垮台是你必须实施ControllerType协议,并且没有办法强制执行它。