ios - 在手势方法中获取节标题单元格

标签 ios swift uitableview uigesturerecognizer

我正在处理一个带有不同部分标题的“UITableView”。部分标题包含用于展开和折叠部分的制表符手势识别。

在部分标题 View 中,我使用图像作为附件图标来向用户显示该部分是展开还是折叠的。

我担心的是当我点击节标题然后控制转到手势方法时。在那个方法中,我应该如何让标题单元格相应地更新图像?

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
    if self.useSearchDefinitions {
        if let ret = tableView.dequeueReusableCell(withIdentifier: INBOX_HEADER_CELL_IDENTIFIER) as? InboxHeaderCell {
            ret.contentView.backgroundColor = UIColor(red: 236 / 255.0, green: 236 / 255.0, blue: 236 / 255.0, alpha: 1.0)
            ret.contentView.tag = section
            ret.lblHeaderTitle?.textColor = UIColor(red: 110 / 255.0, green: 110 / 255.0, blue: 110 / 255.0, alpha: 1.0)
            ret.lblHeaderTitle?.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
            ret.lblHeaderTitle?.text = presenter.sectionTitle(section)

            ret.accessoryImage.image = UIImage(named: "inbox-expand.png")

            // Set tap gesture
            let headerViewTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.headerViewGestureHandler))
            headerViewTapRecognizer.delegate = self
            headerViewTapRecognizer.numberOfTouchesRequired = 1
            headerViewTapRecognizer.numberOfTapsRequired = 1

            ret.contentView.addGestureRecognizer(headerViewTapRecognizer)

            return ret.contentView
        }
    }

    return nil
}

这是获取手势

    func headerViewGestureHandler(_ sender: UIGestureRecognizer)
{
    tableView.beginUpdates()

    if let tag = sender.view?.tag {
        let section = Int(tag)
        let shouldCollapse: Bool = !collapsedSections.contains((section))
        let numOfRows = Int(presenter.numberOfRows(tag))
}

}

我应该如何在此方法中获取特定的点击部分标题单元格,以便我可以相应地更新图像?

提前致谢。

最佳答案

我会推荐:

  1. 将手势代码放在您的部分标题中
  2. 使用“回调”闭包将点击传递回 View Controller

这是一个简单的示例(假设您有一个带有 TableView 的 View Controller ,通过 IBOutlet 连接):

class SimpleSectionHeaderView: UITableViewHeaderFooterView, UIGestureRecognizerDelegate {

    // typical UILabel
    var lblHeaderTitle: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    // this is our "call back" closure    
    var headerTapCallback: (() -> ())?

    func headerViewGestureHandler(_ sender: UIGestureRecognizer) {
        // just for debugging, so we know the tap was triggered
        print("tapped!!!")

        // "call back" to the view controller
        headerTapCallback?()
    }

    func commonInit() {

        // set our backgroundColor
        contentView.backgroundColor = .cyan

        // add a label and set its constraints
        self.addSubview(lblHeaderTitle)
        lblHeaderTitle.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 8.0).isActive = true
        lblHeaderTitle.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0.0).isActive = true

        // Set tap gesture
        let headerViewTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.headerViewGestureHandler))
        headerViewTapRecognizer.delegate = self
        headerViewTapRecognizer.numberOfTouchesRequired = 1
        headerViewTapRecognizer.numberOfTapsRequired = 1

        // add it to self
        self.addGestureRecognizer(headerViewTapRecognizer)

    }

    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)
        commonInit()
    }

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

}

class TableWithSectionHeadersViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var theTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // standard cell registration
        theTableView.register(UITableViewCell.self, forCellReuseIdentifier: "reuseIdentifier")

        theTableView.register(SimpleSectionHeaderView.self, forHeaderFooterViewReuseIdentifier: "simpleHeaderView")

        // make sure these are set (in case we forgot in storyboard)
        theTableView.delegate = self
        theTableView.dataSource = self

    }

    func handleHeaderTap(_ section: Int) -> Void {

        // do whatever we want based on which section header was tapped
        print("View Controller received a \"tapped\" in header for section:", section)

    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let v = tableView.dequeueReusableHeaderFooterView(withIdentifier: "simpleHeaderView") as! SimpleSectionHeaderView

        // set the view's label text
        v.lblHeaderTitle.text = "Section \(section)"

        // set the view's "call back" closure
        v.headerTapCallback = {
            _ in
            self.handleHeaderTap(section)
        }

        return v
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 60;
    }

    // MARK: - Table view data source

    func numberOfSections(in tableView: UITableView) -> Int {
        return 5
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)

        // Configure the cell...
        cell.textLabel?.text = "\(indexPath)"

        return cell
    }

}

这也消除了设置任何 .tag 属性的需要(出于多种原因,这通常是一个坏主意)。

关于ios - 在手势方法中获取节标题单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46469311/

相关文章:

ios - UIKit - Swift - 允许 tableHeaderView 向上滚动,但不能向下滚动

ios - UITableViewCell 未被删除

ios - Iphone 传递对象(导航栏上的按钮返回)

ios - 关于ios Application loader代码设计验证

ios - UIView 子类的 Swift 通用方法

ios - UITableView 的 HeaderFooterView 不根据大小类宽度拉伸(stretch)

ios - 我们什么时候在 Objective-C 中使用 static __unsafe_unretained?

iOS:代码签名错误,证书身份在钥匙串(keychain)中出现多次

ios - 如何比较 WKNavigation 对象

swift - 设置委托(delegate)会导致崩溃,将其保留为空则不会