带有自定义单元格的可扩展/可折叠TableView,用于常见问题

时间:2019-05-06 11:34:50

标签: ios swift uitableview

我想通过自定义 UITableView实现可扩展/可折叠 UITableViewCell,并根据问题/答案文本来调整其侧面。我尝试了不同的方法,但没有一个能如我所愿。如果有人实施了同一件事,请与我们分享项目链接或让我知道它是如何完成的。任何形式的帮助将不胜感激。我正在分享我想要的屏幕截图。enter image description here

这就是我尝试过的。当我滚动表格视图时,它会在单元格之间添加额外的空间,还会弄乱UITextView。

enter code here

// Mark: Table View Delegate Methods

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    let questionTextView = UITextView(frame:CGRect(x: 0, y: 0, width: 265.0, height: 30))
    let answerTextView = UITextView(frame:CGRect(x: 0, y: 0, width: 265.0, height: 30))

    questionTextView.text = questionStringArray[indexPath.row]
    answerTextView.text = answerStringArray[indexPath.row]

    Common.adjustUITextViewHeight(questionTextView)
    Common.adjustUITextViewHeight(answerTextView)

    let cellHeightExpanded:CGFloat = CGFloat(3 + Double(questionTextView.frame.size.height) + 5 + Double(answerTextView.frame.size.height) + 10)
    let cellHeightCollapsed:CGFloat = CGFloat(3 + Double(questionTextView.frame.size.height) + 5)

    if (indexPath.row == selectedQuestion)
    {
        return cellHeightExpanded
    }
    else
    {
        return cellHeightCollapsed
    }
}

// number of rows in table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

   return 5
}

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

// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! FAQsCell
    cell.backgroundColor = UIColor.white

    cell.tvQuestion.text = questionStringArray[indexPath.row]
    cell.tvAnswer.text = answerStringArray[indexPath.row]

    Common.adjustUITextViewHeight(cell.tvQuestion)
    Common.adjustUITextViewHeight(cell.tvAnswer)

    cell.tvAnswer.frame = CGRect(origin: CGPoint(x: cell.tvAnswer.frame.origin.x, y : cell.tvQuestion.frame.origin.y + cell.tvQuestion.frame.size.height), size: CGSize(width: cell.tvAnswer.frame.size.width, height: cell.tvAnswer.frame.size.height))

    if indexPath.row == selectedQuestion {

        cell.backgroundColor = UIColor.okapiCellGrayColorForPendingAppLevel()
        cell.tvQuestion.textColor = UIColor.white
        cell.tvAnswer.textColor = UIColor.white
    }
    else {

        cell.backgroundColor = UIColor.clear
        cell.tvQuestion.textColor = UIColor.blue_grey_700()
        cell.tvAnswer.textColor = UIColor.blue_grey_700()
    }

    return cell
}

// method to run when table view cell is tapped
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    selectedQuestion = indexPath.row
    faqsTableView.reloadData()
}

2 个答案:

答案 0 :(得分:0)

在自定义单元格中添加垂直堆栈视图,并根据所选单元格显示/隐藏答案

class ViewController: UITableViewController {

    var questions = [(question:String,answer:String)]()
    var selectedQuestion = -1

    override func viewDidLoad() {
        super.viewDidLoad()
        questions = [(question:"Question 1",answer:"Answer 1"),(question:"Question 2",answer:"Answer 2"),
                    (question:"Question 3",answer:"Answer 3"),(question:"Question 4",answer:"Answer 4"),
                    (question:"Question 5",answer:"Answer 5")]
        self.view.backgroundColor = .white
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 50
        tableView.register(FAQsCell.self, forCellReuseIdentifier: "FAQsCell")
    }
}
extension ViewController {
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 50
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return questions.count
    }
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FAQsCell") as! FAQsCell
        cell.questionLbl.text = questions[indexPath.row].question
        cell.answerLbl.text = questions[indexPath.row].answer
        if indexPath.row == selectedQuestion {
            cell.backgroundColor = .groupTableViewBackground
            cell.dropDownImgView.image = //upimage
            cell.answerView.isHidden = false
        } else {
            cell.backgroundColor = .white
            cell.dropDownImgView.image = //downimage
            cell.answerView.isHidden = true
        }

        return cell
    }
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        selectedQuestion = indexPath.row
        tableView.reloadData()
    }

}
class FAQsCell: UITableViewCell {

    let stackView = UIStackView()
    let questionLbl = UILabel()
    let dropDownImgView = UIImageView()
    let answerView = UIView()
    let answerLbl = UILabel()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    func commonInit() {

        stackView.axis = .vertical
        stackView.distribution = .fillProportionally
        stackView.spacing = 5
        stackView.alignment = .fill
        stackView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(stackView)

        let questionView = UIView()
        questionView.translatesAutoresizingMaskIntoConstraints = false
        questionView.heightAnchor.constraint(equalToConstant: 35).isActive = true
        stackView.addArrangedSubview(questionView)

        questionLbl.font = UIFont.boldSystemFont(ofSize: 18)
        questionLbl.translatesAutoresizingMaskIntoConstraints = false
        questionView.addSubview(questionLbl)

        dropDownImgView.contentMode = .scaleAspectFit
        dropDownImgView.translatesAutoresizingMaskIntoConstraints = false
        questionView.addSubview(dropDownImgView)

        answerView.translatesAutoresizingMaskIntoConstraints = false
        answerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 35).isActive = true
        stackView.addArrangedSubview(answerView)

        answerLbl.numberOfLines = 0
        answerLbl.lineBreakMode = .byWordWrapping
        answerLbl.font = UIFont.systemFont(ofSize: 17)
        answerLbl.translatesAutoresizingMaskIntoConstraints = false
        answerView.addSubview(answerLbl)

        questionView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(10)-[questionLbl]-(10)-[dropDownImgView(25)]-(10@999)-|", options: [.alignAllCenterY], metrics: nil, views: ["questionLbl":questionLbl, "dropDownImgView": dropDownImgView]))
        dropDownImgView.heightAnchor.constraint(equalTo: dropDownImgView.widthAnchor).isActive = true
        questionView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[questionLbl(25)]-(5)-|", options: [], metrics: nil, views: ["questionLbl":questionLbl]))

        answerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(10)-[answerLbl]-(10)-|", options: [], metrics: nil, views: ["answerLbl":answerLbl]))
        answerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[answerLbl(>=25)]-(5)-|", options: [], metrics: nil, views: ["answerLbl":answerLbl]))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[stackView]-(5@999)-|", options: [], metrics: nil, views: ["stackView":stackView]))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(5)-[stackView]-(5)-|", options: [], metrics: nil, views: ["stackView":stackView]))
    }
}

答案 1 :(得分:-1)

您可以通过约束来实现。

将标题和描述约束赋予底部以进行超级浏览。

之后,相应地更改约束的优先级。

如果您想通过图像理解,请告诉我。