I am in the process of updating my app to iOS10 with Swift 2.3 and Xcode 8 Beta 1 and I have found that there is a UITableViewHeaderFooterContentView
which is blocking touches to the UIButton on my subclass of UITableViewHeaderFooterView
.
On the Xcode 8 Beta 1 simulator the UIButton works on iOS9.3 but not iOS10.
1) Is there any documentation for this?
2) How can I ensure my UI elements are on top of the new Content View in iOS10? (or allow touches through the UITableHeaderFooterContentView
)
Thanks!
Table Header
import UIKit
class TableHeader: UITableViewHeaderFooterView {
@IBOutlet weak var dayLabel: UILabel!
@IBOutlet weak var dateLabel: UILabel!
@IBOutlet weak var addNewEventButton: UIButton!
}
Code In View Controller
dateCell.addNewEventButton
is the UIButton that is no longer receiving touches in iOS10
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let tintColor = TintManager().getTintColour()
let dateCell:TableHeader = tableView.dequeueReusableHeaderFooterViewWithIdentifier("TableHeader") as! TableHeader
//dateCell.bringSubviewToFront(dateCell.addNewEventButton)
dateCell.dayLabel.text = Dates.day.uppercaseString
dateCell.dateLabel.text = Dates.date
dateCell.backgroundView = UIView(frame: dateCell.frame)
dateCell.backgroundView!.backgroundColor = tintColor
dateCell.dayLabel.textColor = UIColor.whiteColor()
dateCell.dateLabel.textColor = UIColor.whiteColor()
dateCell.addNewEventButton.backgroundColor = tintColor
dateCell.addNewEventButton.tag = section
dateCell.addNewEventButton.layer.cornerRadius = 20.0
if (savedEventView.superview === self.view) {
dateCell.addNewEventButton.removeTarget(nil, action: nil, forControlEvents: .AllEvents)
dateCell.addNewEventButton.addTarget(self, action: #selector(ViewController.userPressedAddButtonToInsertSavedEvent(_:)), forControlEvents:.TouchUpInside)
} else {
dateCell.addNewEventButton.removeTarget(nil, action: nil, forControlEvents: .AllEvents)
dateCell.addNewEventButton.addTarget(self, action: #selector(ViewController.userPressedAddNewEventOnTableViewHeader(_:)), forControlEvents:.TouchUpInside)
}
return dateCell
}
The offending view is in fact the contentView
of the UITableViewHeaderFooterView
(see the Apple Docs). So you should be able just to use sendSubview(toBack:)
in order to stop it interfering with touches.
However, it seems that under iOS9 the UITableViewHeaderFooterView
fails to correctly initialise the contentView
if the view is loaded from a NIB. Although the contentView
property is not optional, it is in fact nil, and you get a BAD ACCESS error if you try to access it. Nor can you set a value for contentView
(either in code or as an outlet in IB) because it's a read only property (*). So the only solution I can think of is to use #available
to conditionally include code to move the contentView to the back, if you are running on iOS 10 or newer. I would put the relevant code into your subclass:
override func awakeFromNib() {
if #available(iOS 10, *) {
self.sendSubview(toBack: contentView)
}
}
(*) Indulging in wild speculation, my guess is that Apple based the UITableViewHeaderFooterView
code heavily on UITableViewCell
. Since IB has UITableViewCells
in its object library (and notice these include the cell's contentView
), it can ensure that the cell's contentView is correctly instantiated. But since there is no UITableViewHeaderFooterView
in the object library, there's no way to get the contentView
loaded correctly. Looks like they fixed it in iOS10 by instantiating an empty contentView
. Pity they didn't also add UITableViewHeaderFooterView
to the library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With