开发者

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)")
                }
            }
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜