func textViewDidChange(_ textView: UITextView) {
let size = textView.bounds.size
let newSize = textView.sizeThatFits(CGSize(width: size.width, height: CGFloat.greatestFiniteMagnitude))
if size.height != newSize.height {
UIView.setAnimationsEnabled(false)
tableView?.beginUpdates()
tableView?.endUpdates()
UIView.setAnimationsEnabled(true)
}
}
scrollToRow(at:at:animated:)
поместить в нужный метод делегата UITextView
.let indexPath = IndexPath(row: 0, section: 2)
tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
at: .bottom
? У вас ведь и так клавиатура снизу, вы ещё и скролите вниз. Попробуйте .top
. UITextvView
осталась под клавиатурой. Вы сдвинули бы этот UITextvView
чуток выше, что бы он весь был в поле зрения и включили бы скролл у самого UITextvView
. В таком случаи я не вижу никаких проблем. func textViewDidBeginEditing(_ textView: UITextView) {
tableView.scrollToRow(at: IndexPath(row: 0, section: 4), at: .top, animated: true)
override func numberOfSections(in tableView: UITableView) -> Int {
return 6
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide), name: .UIKeyboardDidHide, object: nil)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
return tableView.dequeueReusableCell(withIdentifier: "First", for: indexPath)
} else if indexPath.section == 1 {
return tableView.dequeueReusableCell(withIdentifier: "Second", for: indexPath)
} else if indexPath.section == 2 {
return tableView.dequeueReusableCell(withIdentifier: "Third", for: indexPath)
} else {
return tableView.dequeueReusableCell(withIdentifier: "Fours", for: indexPath)
}
}
@objc func keyboardDidShow(_ notification: NSNotification) {
let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 2))
let keyboardFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let cellPointY = cell!.frame.origin.y
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y + cellPointY), animated: true)
cell!.frame = CGRect(x: 0, y: cell!.frame.origin.y, width: cell!.frame.width, height: cell!.frame.height + (keyboardFrame.origin.y - cell!.frame.maxY))
}
@objc func keyboardDidHide(_ notification: NSNotification) {
}
}
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide), name: .UIKeyboardDidHide, object: nil)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
return tableView.dequeueReusableCell(withIdentifier: "First", for: indexPath)
} else if indexPath.section == 1 {
return tableView.dequeueReusableCell(withIdentifier: "Second", for: indexPath)
} else if indexPath.section == 2 {
return tableView.dequeueReusableCell(withIdentifier: "Third", for: indexPath)
} else {
return tableView.dequeueReusableCell(withIdentifier: "Fours", for: indexPath)
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath == IndexPath(row: 0, section: 2) {
return UITableViewAutomaticDimension
}
return super.tableView(tableView, heightForRowAt: indexPath)
}
@objc func keyboardDidShow(_ notification: NSNotification) {
keyboardFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
currentOffset = tableView.contentOffset
}
@objc func keyboardDidHide(_ notification: NSNotification) {
}
private var keyboardFrame = CGRect.zero
private var prevNumberOfLines = 1
private var currentOffset = CGPoint.zero
}
extension ViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
let rectOfCell = tableView.rectForRow(at: IndexPath(row: 0, section: 2))
let rectOfCellInSuperView = tableView.convert(rectOfCell, to: tableView.superview)
let rectKeyboardInTableViewSuperView = tableView.convert(keyboardFrame, to: tableView.superview)
if rectOfCellInSuperView.maxY < rectKeyboardInTableViewSuperView.origin.y - 18 {
UIView.setAnimationsEnabled(false)
tableView.beginUpdates()
tableView.endUpdates()
tableView.setContentOffset(currentOffset, animated: false)
UIView.setAnimationsEnabled(true)
} else { // тут ещё добавить условие, когда кол-во строк меняется на одну
currentOffset.y += 16.5
UIView.setAnimationsEnabled(false)
tableView.beginUpdates()
tableView.endUpdates()
tableView.setContentOffset(CGPoint(x: currentOffset.x, y: currentOffset.y), animated: false)
UIView.setAnimationsEnabled(true)
}
print(rectOfCellInSuperView.maxY)
print(rectKeyboardInTableViewSuperView.origin.y)
print(currentOffset.y)
print(tableView.contentOffset.y)
print("***")
}
}
extension UITextView {
var numberOfLines: Int {
let layoutManager = self.layoutManager
let numberOfGlyphs = layoutManager.numberOfGlyphs
var numberOfLines = 0
var index = 0
var lineRange = NSRange()
while (index < numberOfGlyphs) {
layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
index = NSMaxRange(lineRange)
numberOfLines = numberOfLines + 1
}
return numberOfLines
}
}
func textViewDidChange(_ textView: UITextView) {
let rectOfCell = tableView.rectForRow(at: IndexPath(row: 0, section: 2))
let rectOfCellInSuperView = tableView.convert(rectOfCell, to: tableView.superview)
let rectKeyboardInTableViewSuperView = tableView.convert(keyboardFrame, to: tableView.superview)
if rectOfCellInSuperView.maxY < rectKeyboardInTableViewSuperView.origin.y - 18 {
UIView.setAnimationsEnabled(false)
tableView.beginUpdates()
tableView.endUpdates()
UIView.setAnimationsEnabled(true)
tableView.setContentOffset(currentOffset, animated: false)
} else if rectOfCellInSuperView.maxY >= rectKeyboardInTableViewSuperView.origin.y - 18, textView.numberOfLines > prevNumberOfLines {
currentOffset.y += 16.5
UIView.animate(withDuration: 0.2, animations: {
self.tableView.contentOffset = CGPoint(x: self.currentOffset.x, y: self.currentOffset.y)
}, completion: { (succes: Bool) in
UIView.setAnimationsEnabled(false)
self.tableView.beginUpdates()
self.tableView.endUpdates()
UIView.setAnimationsEnabled(true)
self.prevNumberOfLines += 1
})
}
print(rectOfCellInSuperView.maxY)
print(rectKeyboardInTableViewSuperView.origin.y)
print(currentOffset.y)
print(tableView.contentOffset.y)
print("***")
}