如何使用UITableViewCell中的按钮添加TextView

时间:2019-05-04 03:51:11

标签: swift uitableview

我正在尝试让UITableView中的UITableViewCells包含一个项目标签,并在其旁边有一个按钮。最初加载表格时,它仅显示标签和按钮,但是当按下按钮时,我希望展开textView并增加该单元格的行高。

我正在使用界面生成器并自动设置行高。我从IB中的textView开始,0的高度为textView的底部,因此我可以将像元高度限制为5。我的计划是更改textViewtextView.frame.size.height = 100)的高度,并且行高将自动增加。但这不会发生。

我研究了很多不同的方法,但是我的大部分Google搜索都以在输入时动态增加文本高度为问题,而这并不是我想要的。我想发布一些代码,但是我尝试了很多不同的方法(估算行高,手动设置单元格框架,委托和协议,tableView.reloadData()tableView.recalculateRowHeight(),手动设置行高,等等,但并没有取得太大的成功。如果我能找到最佳方法的建议,如果仍然遇到问题,我会发布一些示例代码。最好的情况是动画,但是在这一点上,我不需要动画。

我添加了一个GitLab项目链接:https://gitlab.com/vever343/expandingrow (在此示例代码中,我以textView的高度10开始,然后使用按钮将其增加)

TableViewController代码:

import UIKit

class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, cellProtocol {

    @IBOutlet weak var tableView: UITableView!

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

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? TableViewCell {
            cell.delegate = self
            return cell
        } else {
            return TableViewCell()
        }
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }

    func rowExpanded() {
        tableView.reloadData()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
    }
}

UITableViewCell代码:

import UIKit

protocol cellProtocol {
    func rowExpanded()
}

class TableViewCell: UITableViewCell {

    @IBOutlet weak var textView: UITextView!
    var delegate:MainVC?

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    @IBAction func buttonPressed(_ sender: Any) {
        textView.frame.size.height = 100
        delegate?.rowExpanded()
    }

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

3 个答案:

答案 0 :(得分:2)

为您的textview高度限制创建一个NSLayoutConstraint,然后使用它代替textview.frame.size

import UIKit

protocol cellProtocol {
    func rowExpanded()
}

class TableViewCell: UITableViewCell {

    @IBOutlet weak var textView: UITextView!
    @IBOutlet var textViewHeightConstraint: NSLayoutConstraint!
    var delegate:MainVC?

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    @IBAction func buttonPressed(_ sender: Any) {
        self.textViewHeightConstraint.constant = 100
        UIView.animate(withDuration: 0.3) {    
          self.layoutIfNeeded()   
          self.delegate?.rowExpanded()
        }   

    }

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

对于动画部分,

func rowExpanded() {
   self.tableView.beginUpdates()  
   self.tableView.endUpdates() 
}

更新:如果希望在滚动表视图时保持文本视图状态,还应该查看this示例。

答案 1 :(得分:0)

尝试以此设置行的表格视图高度

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

        return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 40  // this can be an estimated value you choose
} 

确保您的textview的对齐方式设置为自然对齐。 按下按钮后,重新加载表格视图

答案 2 :(得分:0)

@Ocanal的答案是正确的,但是在继续进行开发的过程中,我发现了另一种解决方法,这种方法要容易一些。如果将所有项目都放在StackView中,则可以使用stackView.isHidden,如果适当限制了行高度,自动版式将自动处理行高。