我有一个 UITableView,每个单元格内并排有两个 UITextView。我希望 UITableViewCell 和 UITextView 都增加高度,这样用户就不需要在 UITextView 中滚动。这是我尝试过的:
在 TableViewController 类中:
self.tableView.estimatedRowHeight = 44
self.tableView.rowHeight = UITableViewAutomaticDimension
在 TableViewCell 类中(从 here 获得):
func textViewDidChange(textView: UITextView) {
var frame : CGRect = textView.frame
frame.size.height = textView.contentSize.height
textView.frame = frame
}
当用户键入超出 UITextView 的设置宽度时,UITableView 的高度会从 44 增加到大约 100,而 UITextView 的高度不会增加。我设置了约束,以便 UITextView 的高度等于 UITableViewCell 的高度。
知道为什么会发生这种情况以及如何正确地动态更改 UITextView 和 UITableView 的高度吗?
最佳答案
我的答案是基于我们在生产社交应用程序时使用的内容 Impether ,因为你在 Twitter 上问我你使用过这个应用程序,你看到那里扩展了 UITextView。
首先,我们有一个自定义UITableViewCell包含UITextView
的基类,将展开(该类也有对应的xib文件,可自行设计):
class MultiLineTextInputTableViewCell: UITableViewCell {
//our cell has also a title, but you
//can get rid of it
@IBOutlet weak var titleLabel: UILabel!
//UITextView we want to expand
@IBOutlet weak var textView: UITextView!
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
/// Custom setter so we can initialize the height of the text view
var textString: String {
get {
return textView?.text ?? ""
}
set {
if let textView = textView {
textView.text = newValue
textView.delegate?.textViewDidChange?(textView)
}
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Disable scrolling inside the text view so we enlarge to fitted size
textView?.scrollEnabled = false
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
textView?.becomeFirstResponder()
} else {
textView?.resignFirstResponder()
}
}
}
定义了自定义单元格后,您可以在基于 UITableViewController
的类中使用它,如下所示:
class YourTableViewController: UITableViewController {
//in case where you want to have
//multiple expanding text views
var activeTextView: UITextView?
override func viewDidLoad() {
super.viewDidLoad()
//registering nib for a cell to reuse
tableView.registerNib(
UINib(nibName: "MultiLineTextInputTableViewCell", bundle: nil),
forCellReuseIdentifier: "MultiLineTextInputTableViewCell")
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
//hide keyboard when view controller disappeared
if let textView = activeTextView {
textView.resignFirstResponder()
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
//put your value here
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//put your value here
return 2
}
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let row = indexPath.row
let cell = tableView.dequeueReusableCellWithIdentifier(
"MultiLineTextInputTableViewCell",
forIndexPath: indexPath) as! MultiLineTextInputTableViewCell
let titleText = "Title label for your cell"
let textValue = "Text value you want for your text view"
cell.titleLabel.text = titleText
cell.textView.text = textValue
//store row of a cell as a tag, so you can know
//which row to reload when the text view is expanded
cell.textView.tag = row
cell.textView.delegate = self
return cell
}
override func tableView(tableView: UITableView,
estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
//standard row height
return 44.0
}
override func tableView(tableView: UITableView,
heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView,
canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
}
//extension containing method responsible for expanding text view
extension YourTableViewController: UITextViewDelegate {
func textViewDidEndEditing(textView: UITextView) {
let value = textView.text
//you can do something here when editing is ended
}
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange,
replacementText text: String) -> Bool {
//if you hit "Enter" you resign first responder
//and don't put this character into text view text
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
func textViewDidBeginEditing(textView: UITextView) {
activeTextView = textView
}
//this actually resize a text view
func textViewDidChange(textView: UITextView) {
let size = textView.bounds.size
let newSize = textView.sizeThatFits(CGSize(width: size.width,
height: CGFloat.max))
// Resize the cell only when cell's size is changed
if size.height != newSize.height {
UIView.setAnimationsEnabled(false)
tableView?.beginUpdates()
tableView?.endUpdates()
UIView.setAnimationsEnabled(true)
let thisIndexPath = NSIndexPath(forRow: textView.tag, inSection: 0)
tableView?.scrollToRowAtIndexPath(thisIndexPath,
atScrollPosition: .Bottom,
animated: false)
}
}
}
关于ios - 当UITextView的文本超出1行时展开UITextView和UITableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37014919/