【问题标题】:How to manipulate UITableView to edit cells according to header?如何操作 UITableView 以根据标题编辑单元格?
【发布时间】: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。

标签: ios swift uitableview uikit


【解决方案1】:

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

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

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

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

  4. 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
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多