UITableViewController select header for section
I have a UITableView
with multiple sections. Each section has a section header (a custom view) is there an easy开发者_JS百科 way to detect when someone selects the section header? (Just like didSelectRowAtIndexPath
, but for the header?)
This isn't radically different than @rckoenes answer, but it does provide a more orthodox way of handling events on views rather than using invisible buttons.
I'd rather add a UITapGestureRecognizer to my header view instead of adding invisible buttons and resizing them:
UITapGestureRecognizer *singleTapRecogniser = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)] autorelease];
[singleTapRecogniser setDelegate:self];
singleTapRecogniser.numberOfTouchesRequired = 1;
singleTapRecogniser.numberOfTapsRequired = 1;
[yourHeaderView addGestureRecognizer:singleTapRecogniser];
and then:
- (void) handleGesture:(UIGestureRecognizer *)gestureRecognizer;
You can use gesture.view to see which was touched. Then do whatever you need to do to find out which header it was (tags, data array lookup... )
No there is no way to do it with the UITableViewDelegate
.
What you can do is to add a button the size of the section header view and add it to the view. Set the tag of the button to the section index.
Then just add the UIViewController
as a target for the UIControlEventTouchUpInside
.
Then by looking at the tag of the button you can see which section is clicked.
Here is what worked for me in Swift 2:
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let footerView = UITableViewHeaderFooterView()
footerView.textLabel?.text = "Header Text"
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
tapRecognizer.delegate = self
tapRecognizer.numberOfTapsRequired = 1
tapRecognizer.numberOfTouchesRequired = 1
footerView.addGestureRecognizer(tapRecognizer)
return footerView
}
@objc func handleTap(gestureRecognizer: UIGestureRecognizer) {
print("Tapped")
}
This worked for evaluating the section and row. I hope it helps everybody else who is struggling to get this work properly...
override func viewDidLoad() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(sectionTapped(sender:)))
tableView?.addGestureRecognizer(tapGesture)
tapGesture.delegate = self as? UIGestureRecognizerDelegate
}
@objc func sectionTapped(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.ended {
guard let tableView = self.tableView else {
return
}
if let view = sender.view {
let tapLocation = sender.location(in: tableView)
if let tapIndexPath = tableView.indexPathForRow(at: tapLocation) {
if (tableView?.cellForRow(at: tapIndexPath) as? UITableViewCell) != nil {
// do something with the row
print("tapped on row at index: \(tapIndexPath.row)")
}
} else {
for i in 0..<tableView.numberOfSections {
let sectionHeaderArea = tableView.rectForHeader(inSection: i)
if sectionHeaderArea.contains(tapLocation) {
// do something with the section
print("tapped on section at index: \(i)")
}
}
}
}
}
}
Here is a little bit updated version of Taku's answer.
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(sectionTapped(sender:)))
tableView.addGestureRecognizer(tapGesture)
tapGesture.delegate = self
}
@objc func sectionTapped(sender: UITapGestureRecognizer) {
guard sender.state == .ended else { return }
let tapLocation = sender.location(in: tableView)
if let tapIndexPath = tableView.indexPathForRow(at: tapLocation),
let cell = tableView.cellForRow(at: tapIndexPath) {
// TODO: Do something with row
print("tapped on row at index: \(tapIndexPath.row)")
} else {
for section in 0..< tableView.numberOfSections {
let headerRect = tableView.rectForHeader(inSection: section)
if headerRect.contains(tapLocation) {
// TODO: Do something with the section
print("Tapped on section at index: \(section)")
}
}
}
}
精彩评论