访问UITableView标头视图

时间:2019-05-09 10:03:50

标签: ios swift uitableview

我有一个UITableView,其中节标题视图包含一个UITextField,用户可以键入值。当我要保存用户键入的值时,我需要访问表节标题。

我尝试使用方法headerView(forSection:),然后将headerView(forSection: 0)!作为测试来确保节头确实存在,但是每次运行程序时,方法所在的行返回错误“解开可选值时意外发现nil”。

我也曾尝试标记UITextField,但是当我尝试使用certainTableView.viewWithTag(_ tag:)访问节头并将结果UIView强制转换为UITextField时,在进行强制转换的行会抛出错误,说“无法将类型'UITableView'的值转换为'UITextField'。”

这两个错误在我看来都是很奇怪的。在第一种情况下,我确保节头存在,但该方法返回了nil。在第二种情况下,返回的标记视图应为UITableViewHeaderFooterView类型,但类型为UITableView。有人可以建议出现这种情况的任何可能原因以及如何纠正吗?

或者,是否有更好的方法来访问节标题视图,以便我可以将键入的文本保存在UITextField中?

下面是我在第一种情况下使用的细节。

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?中,我返回了一个包含UITextField的UIView。在需要保存键入的用户数据的表视图中,我有一个按钮,当用户点击它时,将保存数据。在该选择器中,我具有以下内容:

//save item
    let a = addItemTableView.headerView(forSection: 0)!
    let b = a.subviews[0] as! UITextField
    let c = b.text ?? ""
    someNSManagedObject.text = c

我上面提到的错误出现在第一行。

3 个答案:

答案 0 :(得分:1)

首先将属性添加到模型textFieldData中,以将textField数据保存在其中。

然后在您的HeaderViewClass中添加一个闭包var textFieldDidChange: ((String) -> Void)?

class HeaderViewClass: UITableViewHeaderFooterView {
// MARK:- IBOutlets
@IBOutlet weak var textField: UITextField!

// MARK:- Variable
var textFieldDidChange: ((String) -> Void)?

// MARK:- Functions
func fill(with model: Model) {
    textField.delegate = self
    textField.text = model.textFieldData
}
}

extension HeaderViewClass: UITextFieldDelegate {
    func textFieldDidChange(_ textField: UITextField) {    
        textFieldDidChange?(textField.text)
    }
}

在您的viewController类中

func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
    let footerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: PlaceOrderFooterView.id) as! PlaceOrderFooterView
    footerView.fill(with: models[section])

    footerView.textFieldDidChange = { [unowned self] text in
        self.models[section].textFieldData = text
    }

    return footerView
}

现在,只要更改任何textField数据,您的模型对象就具有更新的值。

答案 1 :(得分:0)

使用您的方法

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

当您返回包含UITextField的自定义标头时,将其分配给您的控制器,这样,您将在UITextFieldDelegate函数下按用户获取所有键值

答案 2 :(得分:0)

在阅读this question中的帖子后,我得到了一个提示,发现在func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?方法中,我应该返回 UITableViewHeaderFooterView 而不是以前的 UIView 。当我将返回的对象的类型更改为UITableViewHeaderFooterView时,其他所有内容保持不变(即,将UITextField添加到UITableViewHeaderFooterView),我设法通过headerView(forSection:)方法访问了UITableViewHeaderFooterView中的UITextField。

更清晰地说,在苹果的文档中,函数声明为func headerView(forSection section: Int) -> UITableViewHeaderFooterView?,表明返回值是UITableViewHeaderFooterView,为了使用该方法访问标题视图,返回的值来自{{1 }}应该是UITableViewHeaderFooterView,而不是任何其他常规UIView或UIView子类。

希望这会有所帮助。