如何操作 UITableView 以根据标题编辑单元格?

Posted

技术标签:

【中文标题】如何操作 UITableView 以根据标题编辑单元格?【英文标题】:How to manipulate UITableView to edit cells according to header? 【发布时间】:2019-12-22 20:00:27 【问题描述】:

我几乎完成了我的小家庭项目。但是一些主要功能我不确定如何实现。

我有一个 UITableViewController 有 2 个原型自定义单元格。一个作为粘性标题,一个作为要在整个 tableview 中出列的内容。 我需要 根据来自标题的输入更改和重新填充“ContentCell”标签。

这是视图控制器的图片:

我希望标题中的文本字段更改 numberOfRowsInSection 和单元格的标签。执行此操作的最佳方法是什么?

这是我已经拥有的:

ReaderViewController.Swift:

import UIKit

class ReaderViewController: UITableViewController 


    let maxRows = 30
    var headerView: UIView?
    var book: Book?
    var stepperValue: Int?
    var rowCount = Int()

    override func viewDidLoad() 
        super.viewDidLoad()
        if let book = book
            print(book.book)
         else 
            print("no book")
        
        tableView.rowHeight = 100

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
        return 150.0
    

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
        let view = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as? HeaderCell
        view?.backgroundColor = .cyan
        view?.stepper.layer.cornerRadius = 3.0
        headerView = view
        return view
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        if let num = stepperValue
            if let count = book?.chapters[num].verses.count
                rowCount = count
             else 
                rowCount = 2
            
        
        print(rowCount)
        return rowCount
    

    @IBAction func textFieldValueChanged(_ sender: UITextField) 
        if let text = sender.text
            if text.isEmpty
                stepperValue = 1
             else 
                stepperValue = Int(text)
                print(stepperValue)
            
        
        tableView.reloadData()
    
    @IBAction func finishedEditing(_ sender: UITextField) 
        if let text = sender.text
            stepperValue = Int(text)
        
        tableView.reloadData()
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier:
            "ContentCell", for: indexPath) as! ContentCell

        if let komik = cell.lbl
            if let num = stepperValue 
                komik.text = book?.get(chapter: num, verse: indexPath.row)
             else 
                //print("no text")
            

        
        // Configure the cell...

        return cell
    

HeaderCell.Swift:

import UIKit

class ContentCell: UITableViewCell 

    @IBOutlet weak var lbl: UILabel!

    override func awakeFromNib() 
        super.awakeFromNib()
        // Initialization code
    



    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    


ContentCell.swift:

import UIKit

class HeaderCell: UITableViewCell 

    override func awakeFromNib() 
        super.awakeFromNib()
        // Initialization code
    

    @IBOutlet weak var stepper: UIStepper!
    @IBOutlet weak var chapterTextField: UITextField!

    @IBAction func changeChapters(_ sender: UIStepper) 
        if chapterTextField.text!.isEmpty
            sender.value = sender.stepValue
            chapterTextField.text = "\(sender.value)"
         else 
            chapterTextField.text = "\(Int(sender.value))"
        


    


    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    


应用已构建,但文本字段未填充 ContentCell。

【问题讨论】:

您的总体方法是正确的,但我认为您的 textfieldValueChanged 不会被调用,因为文本字段位于标题单元格中。仅当它在标题单元格中时才会调用它,然后您需要使用委托将调用传递给控制器​​。如果您需要更清楚地说明这一点,请告诉我。 是的,我确实需要更清楚一点。你能举个例子吗? 好的,我会添加我的答案。 如果它对你有用,你能接受作为答案吗? 它构建但文本字段仍然没有填充 ContentCells。 【参考方案1】:

跟进我对问题的评论。这是我的答案。

    删除断开界面生成器 @IBAction func textFieldValueChanged(_ sender: UITextField @IBAction func finishedEditing(_ sender: UITextField) 来自 ReaderViewController。

    我正在使用委托,但您也可以使用块与控制器进行通信。

    finishedEditing 方法不是必需的,因为您会根据 textField 中的每次更改更新步进器。

    headerCell 中连接并将valueChangeMethod 放在1 中,然后从该方法中调用委托方法。

以下是进行上述更改后您的课程的外观。 在 ReaderViewController 中执行步骤 1 和 3

    //ReaderViewController

    import UIKit

    class ReaderViewController: UITableViewController, HeaderCellDelegate 


    let maxRows = 30
    var headerView: UIView?
    var book: Book?
    var stepperValue: Int?
    var rowCount = Int()

    override func viewDidLoad() 
        super.viewDidLoad()
        if let book = book
            print(book.book)
         else 
            print("no book")
        
        tableView.rowHeight = 100

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    

    //HeaderCellDelegate
    func headerCellTextFieldChanged(_ textField: UITextField) 
        if let text = textField.text
            if text.isEmpty
                stepperValue = 1
             else 
                stepperValue = Int(text)
                print(stepperValue)
            
        
        tableView.reloadData()
    

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
        return 150.0
    

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
        let view = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as? HeaderCell
        view?.textFieldDelegate = self
        view?.backgroundColor = .cyan
        view?.stepper.layer.cornerRadius = 3.0
        headerView = view
        return view
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        if let num = stepperValue
            if let count = book?.chapters[num].verses.count
                rowCount = count
             else 
                rowCount = 2
            
        
        print(rowCount)
        return rowCount
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier:
            "ContentCell", for: indexPath) as! ContentCell

        if let komik = cell.lbl
            if let num = stepperValue 
                komik.text = book?.get(chapter: num, verse: indexPath.row)
             else 
                //print("no text")
            

        
        // Configure the cell...

        return cell
    

在 HeaderCell 文件中执行步骤 2 和 4

//HeaderCell

protocol HeaderCellDelegate

    func headerCellTextFieldChanged(_ textField: UITextField)


import UIKit

class HeaderCell: UITableViewCell 

    override func awakeFromNib() 
        super.awakeFromNib()
    

    weak var textFieldDelegate: HeaderCellDelegate?

    @IBOutlet weak var stepper: UIStepper!
    @IBOutlet weak var chapterTextField: UITextField!

    @IBAction func changeChapters(_ sender: UIStepper) 
        if chapterTextField.text!.isEmpty
            sender.value = sender.stepValue
            chapterTextField.text = "\(sender.value)"
         else 
            chapterTextField.text = "\(Int(sender.value))"
        
    


    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    

       @IBAction func textFieldValueChanged(_ sender: UITextField) 
        textFieldDelegate?.headerCellTextFieldChanged(sender)
       
    

内容单元不需要更改。

这绝对可以。 让我知道它是否没有以及通过放置断点不会调用什么方法。

【讨论】:

【参考方案2】:

HeaderCell 中添加textFieldValueChangedfinishedEditing 并连接它们,添加两个代表回调的变量:

class HeaderCell: UITableViewCell 
    var textFieldValueChanged: ((UITextField) -> ())?
    var finishedEditing: ((UITextField) -> ())?

    @IBAction func textFieldValueChanged(_ sender: UITextField) 
        textFieldValueChanged?(sender)
    

    @IBAction func finishedEditing(_ sender: UITextField) 
        finishedEditing?(sender)
    

    //  Rest of your code 


在你的ReaderViewController 里面tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) 这样做:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
        let view = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as? HeaderCell
        view?.backgroundColor = .cyan
        view?.stepper.layer.cornerRadius = 3.0
        headerView = view

        view?.textFieldValueChanged =  textField in
            if let text = sender.text
                if text.isEmpty
                    stepperValue = 1
                 else 
                    stepperValue = Int(text)
                    print(stepperValue)
                
            

            self.tableView.reloadData()
        

        view?.finishedEditing =  textField in
            if let text = sender.text
                stepperValue = Int(text)
            

            self.tableView.reloadData()
        

        return view

从您的ReaderViewController 中删除并断开与界面构建器@IBAction func textFieldValueChanged(_ sender: UITextField)@IBAction func finishedEditing(_ sender: UITextField) 的连接。

【讨论】:

【参考方案3】:

您只需在代码中添加两件事。 首先,您需要为 UITextFieldDelegate 添加扩展并添加委托功能。

func textFieldDidBeginEditing(textField: UITextField!)     //delegate method
//whenever you change anything inside of your text field this function will be called.


override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
        let view = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as? HeaderCell
        view?.backgroundColor = .cyan
        view?.stepper.layer.cornerRadius = 3.0
        view?.chapterTextField.delegate = self
        headerView = view

        return view
    

【讨论】:

以上是关于如何操作 UITableView 以根据标题编辑单元格?的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 单手势行滑动动作

iOS 编辑UITableView(根据iOS编程编写)

处于编辑模式时的 UITableViewCell 宽度问题

如何在 UITableView 中刷新单节标题的文本

如何从按钮单击中获取 UITableview cell.textlabel.text 值?

在 TableView 中同时启用多编辑和单编辑样式