I use code to create the view (with subviews) for UIViewController
's this is how I do it:
override loadView()
class MYViewController: UIViewController {
var myView: MyView! { return self.view as MyView }
override func loadView() {
view = MyView()
}
}
and here is how I create my custom view:
class MyView: UIView {
// MARK: Initialization
override init (frame : CGRect) {
super.init(frame : frame)
addSubviews()
setupLayout()
}
convenience init () {
self.init(frame:CGRect.zero)
}
required init(coder aDecoder: NSCoder) {
fatalError("This class does not support NSCoding")
}
// MARK: Build View hierarchy
func addSubviews(){
// add subviews
}
func setupLayout(){
// Autolayout
}
// lazy load views
}
I do this for all my View Controllers and I am looking for more elegant way, because this process is repetitive, so is there any solution for make that generic for example, create a super abstract class, or create an extension for UIViewController and UIView, Protocols ? I am new for swift and I think that Swift can have a better elegant solution with it's modern patterns
If you are wanting to create many different controllers with custom view classes my recommended solution would be along these lines:
First implement a custom view subclass the way you want to be able to use it, here I have used the one you had in your question. You can then subclass this anywhere you need it and just override the relevant methods.
class CustomView: UIView {
// MARK: Initialization
override init(frame: CGRect) {
super.init(frame: frame)
addSubviews()
setupLayout()
}
required init() {
super.init(frame: .zero)
addSubviews()
setupLayout()
}
required init(coder aDecoder: NSCoder) {
fatalError("This class does not support NSCoding")
}
// MARK: Build View hierarchy
func addSubviews(){
// add subviews
}
func setupLayout(){
// Autolayout
}
}
Then create a generic custom view controller that allows specification of a class as a generic parameter so that you can easily create a controller with a custom view class.
class CustomViewController<T: CustomView>: UIViewController {
var customView: T! { return view as! T }
override func loadView() {
view = T()
}
init() {
super.init(nibName: nil, bundle: nil)
}
}
Then if you wanted to define a new custom view and create a controller that uses it you can simply:
class AnotherCustomView: CustomView { /* Override methods */ }
...
let controller = CustomViewController<AnotherCustomView>()
Boom!
If you wanted you could even typealias this new controller type to make it even more elegant:
class AnotherCustomView: CustomView { /* Override methods */ }
...
typealias AnotherCustomViewController = CustomViewController<AnotherCustomView>
let controller = AnotherCustomViewController()