We can do this by adding a "callback" closure to your cell.
When the text view is edited, the cell class will "call back" to the controller, where we can tell the table view to recalculate row heights (as well as saving the edited text).
Here's a simple cell layout with constraints. Make sure to disable scrolling on the text view:

Note that the height of the cell at design-time doesn't matter... our constraints will allow auto-layout to handle that.
Result:

Here's the example code:
class ExampleCell: UITableViewCell, UITextViewDelegate {
@IBOutlet var recordButton: UIButton!
@IBOutlet var lyricsField: UITextView!
var callback: ((String) -> ())?
override func didMoveToSuperview() {
super.didMoveToSuperview()
// make sure scroll is disabled
lyricsField.isScrollEnabled = false
// make sure delegate is set
lyricsField.delegate = self
// if these are set in Storyboard this func is not needed
}
func textViewDidChange(_ textView: UITextView) {
let str = textView.text ?? ""
// tell the controller
callback?(str)
}
}
class ExampleTableViewController: UITableViewController {
var myData: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
// start with 20 sample strings for our data
// fill data array with 30 strings
myData = (1...30).map { "This is row \($0)" }
// give the second row some longer sample text
myData[1] = "Some sample text so we see that the text view height will be automatically handled by auto-layout."
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "exampleCell", for: indexPath) as! ExampleCell
cell.lyricsField.text = myData[indexPath.row]
// set the closure
weak var tv = tableView
cell.callback = { [weak self] str in
guard let self = self, let tv = tv else { return }
print("called back", str)
// update our data with the edited string
self.myData[indexPath.row] = str
// we don't need to do anything else here
// this will force the table to recalculate row heights
tv.performBatchUpdates(nil)
}
return cell
}
}
and here's the Storyboard source for reference:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="UxY-Y6-LYS">
<device id="retina3_5" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Example Table View Controller-->
<scene sceneID="HKA-46-9zH">
<objects>
<tableViewController id="UxY-Y6-LYS" customClass="ExampleTableViewController" customModule="Temp" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="ZaD-4v-hEm">
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="exampleCell" rowHeight="141" id="1bW-gv-rnI" customClass="ExampleCell" customModule="Temp" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="320" height="141"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="1bW-gv-rnI" id="H65-Gy-hPe">
<rect key="frame" x="0.0" y="0.0" width="320" height="141"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5rZ-Jh-Wyd">
<rect key="frame" x="96" y="11" width="128" height="30"/>
<color key="backgroundColor" red="0.85215073819999998" green="0.88016217949999997" blue="0.94548028709999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Record"/>
</button>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" keyboardDismissMode="onDrag" text="The Text View" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="ddd-0L-1pM">
<rect key="frame" x="24" y="49" width="272" height="81"/>
<color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" systemColor="labelColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<constraints>
<constraint firstItem="ddd-0L-1pM" firstAttribute="top" secondItem="5rZ-Jh-Wyd" secondAttribute="bottom" constant="8" id="MHf-Yq-xQq"/>
<constraint firstAttribute="trailingMargin" secondItem="ddd-0L-1pM" secondAttribute="trailing" constant="8" id="QMH-AZ-j7k"/>
<constraint firstItem="5rZ-Jh-Wyd" firstAttribute="leading" secondItem="H65-Gy-hPe" secondAttribute="leadingMargin" constant="80" id="TYR-1f-iit"/>
<constraint firstAttribute="trailingMargin" secondItem="5rZ-Jh-Wyd" secondAttribute="trailing" constant="80" id="Yf1-2g-dlf"/>
<constraint firstItem="5rZ-Jh-Wyd" firstAttribute="top" secondItem="H65-Gy-hPe" secondAttribute="topMargin" id="gaW-td-egM"/>
<constraint firstItem="ddd-0L-1pM" firstAttribute="bottom" secondItem="H65-Gy-hPe" secondAttribute="bottomMargin" id="lKj-ML-H4Q"/>
<constraint firstItem="ddd-0L-1pM" firstAttribute="leading" secondItem="H65-Gy-hPe" secondAttribute="leadingMargin" constant="8" id="uxs-rD-Pdj"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="lyricsField" destination="ddd-0L-1pM" id="9Nz-Ru-psp"/>
<outlet property="recordButton" destination="5rZ-Jh-Wyd" id="qNA-Up-zLK"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="UxY-Y6-LYS" id="cmh-tD-hLg"/>
<outlet property="delegate" destination="UxY-Y6-LYS" id="xk4-oC-WNJ"/>
</connections>
</tableView>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="7mc-zX-bKw" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="330" y="127.5"/>
</scene>
</scenes>
<resources>
<systemColor name="labelColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
Edit in response to comment....
Your constraints in your cell are all wrong...
Here's how they look from your original xib:

Here's how they should look:

Important: your stack view settings need to be:
