Expand UITextView and UITableView When UITextView's Text Extends Beyond 1 Line
My answer is based on what we exactly use in production of our social app Impether, since you asked me on Twitter that you used the app and you saw expanding UITextView there.
First of all, we have a custom UITableViewCell based class containing the UITextView
, which will be expanded (this class has a corresponding xib file also, which you can design on your own):
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()
}
}
}
Having a custom cell defined, you can use it in a UITableViewController
based class like that:
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)
}
}
}
Expand UITextView and then scroll after certain point
It's better to make a default height constraint and connect it's outlet and play with it's constant
self.txH.constant = newHeight
self.view.layoutIfNeeded()
Dynamic expand UITextView
When you end the editing of your text write this.
- (void) textViewDidEndEditing:(UITextView *)textView
{
CGRect frame = myTextView.frame;
frame.size.height = myTextView.contentSize.height;
myTextView.frame = frame;
}
Swift / how to use UITextView with dynamic height INSIDE UITableViewCell with dynamic height
Get programmatically height of textview...
let textView = UITextView()//your Text view
let sizeThatShouldFitTheContent = textView.sizeThatFits(textView.frame.size)
let height = sizeThatShouldFitTheContent.height
OR try this demo...
Self-sizing UITextView in a UITableView
https://www.damienpontifex.com/posts/self-sizing-uitableviewcell-with-uitextview-in-ios8/
Related Topics
iOS Uiimagepickercontroller: Any Way of Getting the Date of the Chosen Picture
Horizontal Paging Uicollectionview with Automatic Item Size in a Vertical Stack View
Swift 3 Filter Array of Dictionaries by String Value of Key in Dictionary
Passing Data Between Interface Controllers in Watchkit
Google Signin Cocoapods Deprecated
Format String with Variadic Arguments
Get Total Include Months Between 2 Date in Swift
Error When Trying to Save a Captured Image in Swift
Nsfilemanager Moveitem Throws Error Code=513
How to Create an Alert in a Swift File Model That Works for Various View Controller
Programmatically Obtaining the Imei or Udid of an iOS Device
How to Make Designable Textfield Code Class in Swift
Can't Copy File from Bundle to Documents Directory in iOS
iOS PDFkit Displaymode = Singlepage Only Shows the First Page of the PDF
Uitextview as Inputaccessoryview Doesn't Render Text Until After Animation