hopy
hopy

Reputation: 615

How to make Swift protocol conformed by a specific kind of Class?

I wrote a protocol in Swift:

protocol FooDelegate{
    titleImage:UIImage? {get}
}

I want to make sure that the class that conforms to it must be a UITableViewController type.

In other words:

// ViewController conform FooDelegate is OK,Because ViewController 
// is inherit from UITableViewController!
class ViewController:UITableViewController,FooDelegate /* compile ok */{

}

// OtherVC is failed to conform FooDelegate,Because it is not inherit
// from UITableViewController.
class OtherVC:UIViewController,FooDelegate /* will compile error */{

}

How to do that?

I changed FooDelegate's definition to this:

protocol FooDelegate where Self:UITableViewController {
    var titleImage:UIImage? {get}
}

But it does not seem to work.

* FIX PART *: Use Self:UITableViewController is OK!!!

But when I write below is wrong when compiling :

class StubClass{
    var delegate:FooDelegate!

    func invoke(){
        let idxSet = ...
        delegate.tableView.reloadSections(idxSet, with: .none) //Error:Value of type 'FooDelegate' has no member 'tableView'
    }
}

Please look at the line that Error above. Isn't there any tableView property in delegate? delegate is conform to FooDelegate,and FooDelegate make Self:UITableViewController,and UITableViewController must have tableView property??!!

What's wrong here??? Thanks :)

Upvotes: 0

Views: 780

Answers (2)

Mukesh
Mukesh

Reputation: 2902

As tableView property is not visible to the protocol declaration you just need to add the tableView property in the protocol. Something like this:

@objc protocol FooDelegate where Self: UITableViewController {
    var tableView: UITableView { get }
}

class SimpleTableView: UITableViewController, FooDelegate {

}

let delegate: FooDelegate? = SimpleTableView()

delegate?.tableView.reloadData()

Remeber to add @objc in protocol declaration.

Upvotes: 3

Nader
Nader

Reputation: 1148

Try this:

protocol FooDelegate: class where Self: UITableViewController {
    // code
}

And if you want certain extensions to be accessible by UITableViewController:

protocol FooDelegate {
    // code
}

extension FooDelegate where Self: UITableViewController {
    // code
}

Upvotes: 1

Related Questions