dk_dev dk_dev - 4 months ago 47
Swift Question

didSelectRowAtIndexPath not called in TableView defined in SubView defined in xib

I have been trying to create a custom view loaded through xib that contains a button and tableview. The table view is shown or hidden when button is pressed.
This interaction works and the table is created / shown. The problem I have is that I can not click on the table rows.
I have been looking all over and haven't found a solution that works.
I made sure that delegate and dataSource are set. I also do not have a GestureRecognizer for the ViewController it is used in that could absorb the touch.

Does anybody have an idea what I am missing?

Here is the code of this custom view:

class SubUnitSpinner : UIView, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var spinnerTableView: UITableView!
let subUnitNames: [String] = ["World", "Add/Remove"]

override init( frame: CGRect ) {
super.init(frame: frame)

loadViewFromNib()
setupTableView()
}

required init?( coder aDecoder: NSCoder ) {
super.init(coder: aDecoder)

loadViewFromNib()
setupTableView()

}

func setupTableView() {
spinnerTableView.delegate = self
spinnerTableView.dataSource = self
spinnerTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
spinnerTableView.rowHeight = 30
spinnerTableView.userInteractionEnabled = true
spinnerTableView.allowsSelection = true
spinnerTableView.hidden = true

}

func loadViewFromNib() {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "SubUnitSpinner", bundle: bundle)
let xibView = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
xibView.frame = bounds
xibView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.addSubview(xibView)
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = spinnerTableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell;
cell.userInteractionEnabled = true
cell.textLabel?.text = subUnitNames[indexPath.row]
cell.tag = indexPath.row
return cell;
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//Interaction
print("cell with path: \(indexPath.row)")
}


@IBAction func spinnerTabbed(sender: AnyObject) {
spinnerTableView.hidden = !spinnerTableView.hidden
} }


Update:

View Layout creation:

The xib view layout has been defined in the "storyboard" and the File's Owner set to SubUnitSpinner. The IBOutlet and IBAction where created by ctrl drag and drop.

Usage in UIViewController:

I use it as part of a UIViewController which also has been defined in the storyboard. I added a UIView and declared the Custom Class to be SubUnitSpinner.
The SubUnitSpinner with layout as defined in xib shows up when running it and the button is clickable, the UITableView is shown / hidden when button is shown. The only thing not working is clicking on the tableView cells.

Is something wrong with the setup?

Answer

I just took your code and added to a dummy project to check. I did this for your method

required init?( coder aDecoder: NSCoder ) {
super.init(coder: aDecoder)
// removed the load from nib and setup tableview
}

In my case I did the following to add the SubUnitSpinner view to my parent view. Hope you did the same

let aTestView = SubUnitSpinner(frame: CGRectMake(50, 200, 200, 200))
view.addSubview(aTestView)

Also double check if you have connected any delegate and datasource from xib. All in all, your code looks fine and I was able to click on it properly. The below are my results that I achieved.

enter image description here enter image description here