liuyaodong
liuyaodong

Reputation: 2567

How to declare a swift class with a property that conforms to some protocol

Is it possible for swift to have a ViewController class, initialized from xib, has a property that is also a subclass of UIViewController and conforms to some protocol?

    protocol SomeProtocol {
        // Some methods
    }

    class ViewController: UIViewController {
        // contentView is initialized from xib
        @IBOutlet weak var contentView: UIView!

        // I'd like to declare anotherViewController both conforms to 'SomeProtocol' 
        // and a subclass of UIViewController
        var anotherViewController: UIViewController!
        ...
    }  

When I declare ViewController as an generic class, say class ViewController<T: UIViewController, SomeProtocol>, I get an error :

"Variable in a generic class cannot be presented in Objective-C"

So how can I fulfil it if I cannot use generic class?

Upvotes: 2

Views: 1530

Answers (2)

Michael Curtis
Michael Curtis

Reputation: 574

So I hope I am not misunderstanding the question as well, but it sounds like you may want a multiple-inheritance object level mixin such as:

let myVC: ViewController, SomeProtocol

Unfortunately, Swift does not support this. However, there is a somewhat awkward work-around that may serve your purposes.

struct VCWithSomeProtocol {
    let protocol: SomeProtocol
    let viewController: UIViewController

    init<T: UIViewController>(vc: T) where T: SomeProtocol {
        self.protocol = vc
        self.viewController = vc
    }
}

Then, anywhere you need to do anything that UIViewController has, you would access the .viewController aspect of the struct and anything you need the protocol aspect, you would reference the .protocol.

For Instance:

class SomeClass {
   let mySpecialViewController: VCWithSomeProtocol

   init<T: UIViewController>(injectedViewController: T) where T: SomeProtocol {
       self.mySpecialViewController = VCWithSomeProtocol(vc: injectedViewController)
   }
}

Now anytime you need mySpecialViewController to do anything UIViewController related, you just reference mySpecialViewController.viewController and whenever you need it to do some protocol function, you reference mySpecialViewController.protocol.

Hopefully Swift 4 will allow us to declare an object with protocols attached to it in the future. But for now, this works.

Hope this helps!

Upvotes: 0

radex
radex

Reputation: 6556

Please forgive me if I misunderstood your problem, but I think what you want to do is declare a new type that inherits from UIViewController and conforms to SomeProtocol, like so:

protocol SomeProtocol { }

class VCWithSomeProtocol: UIViewController, SomeProtocol {

}

class ViewController: UIViewController {
    var anotherViewController: VCWithSomeProtocol!
}

Upvotes: 1

Related Questions