janusfidel
janusfidel

Reputation: 8106

How to properly set a property in a protocol from a conforming class?

I am writing a custom table header view that can expand/collapse, I wrote a protocol for it like below:

protocol ExpandableHeadViewDelegate{
    var expandStateReference   :  [String : Bool] { get set }
    var tblVw                  :   UITableView { get set }
    func didTapActionFromHeadVw(_ view: ExpandableHeadView, tag: Int)
}

Here is my expandable head view class, what Im trying to achieve is when this view is tapped I will be able to call the methods that I need from the UITableView where expandableView is embedded:

class ExpandableHeadView: UIView {
    var delegate : ExpandableHeadViewDelegate?
    //set up tap recognizer
    .
    .
    .
    .
    private func viewTapped {
        if let delegate = delegate {
            delegate.tblVw.reloadData()
        }
    }

}

My viewcontroller that utilizes this class is as below:

class PlayersViewController: UIViewController,UITableViewDelegate,
UITableViewDataSource, ExpandableHeadViewDelegate {
    var expandedCells = [String : Bool]() //
    @IBOutlet var tableVw: UITableView! // compile time error
}

The issue I am facing is even though I declare my 'var tableVw' in my delegate class, Xcode gives me an error:

Protocol requires property 'tableVw' with type 'UITableView'; do you want to add stub?

Setting var expandedCells .. however sets properly. If I set my tableVw as non-IBOutlet it can compile, but I want my tableVw to be an IBOutlet property.

EDIT: Adding a stub variable for tableVw and assigning my tableView IBOutlet to it works. But Im still curious if this can be achieved without using a stub variable

internal var tableVw: UITableView?
@IBOutlet  var tableView: UITableView!
.
.
func viewDidload {
   self.tableVw = self.tableView
}

Upvotes: 0

Views: 320

Answers (1)

Losiowaty
Losiowaty

Reputation: 8006

Quite simply - declare the property in your protocol as UITableView!. The ! matters - a lot.

! makes a variable an optional, but an explicitly unwrapped one. This basically means, that the unwrapping is done for you, under the hood. You promise the compiler, that although this variable can contain a nil, you will make sure it will be set with a proper value before you try to access it. In case of IBOutlets this is done for you by the SDK.

Upvotes: 1

Related Questions