Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom UIView for an UIViewController in Swift

I use code to create the view (with subviews) for UIViewController's this is how I do it:

  1. 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

like image 295
iOSGeek Avatar asked Apr 12 '16 18:04

iOSGeek


People also ask

How do I present UIView in Swift?

Select UIViewController or any subclass of ViewController i.e tableviewController under Subclass of ▸ Make sure Also create xib file is checked ▸ Select language ▸ Next ▸ Select target ▸ Create the xib and file under your project directory. It'll automatically creates relationship between your class and xib.

What is the difference between UIView and UIViewController?

They are separate classes: UIView is a class that represents the screen of the device of everything that is visible to the viewer, while UIViewController is a class that controls an instance of UIView, and handles all of the logic and code behind that view.

What is UIView in Swift?

The UIView class is a concrete class that you can instantiate and use to display a fixed background color. You can also subclass it to draw more sophisticated content.


1 Answers

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()
like image 140
George Green Avatar answered Sep 25 '22 14:09

George Green