移动到 UITableViewCell 中嵌入的 UITextView 中的新行时光标消失
Cursor Disappearing When moving to new line in UITextView embedded in UITableViewCell
我在 UITableViewCell 中嵌入了一个 UITextView。
在更新 UITextView 时调用 reloadTableView() 实现 UITableViewCell 在 UITextView 变得太大或太小时自动调整大小。
问题是当通过为前一行创建一个太大的单词或按 return 移动到一个全新的行时,光标不会立即出现。相反,光标将消失并且应该在新行上的字符或单词无法看到,直到添加了一个额外的字符,此时它才应该出现。你可以在 giphy 上的 gif link 中看到问题:
gif image of problem
值得注意的是,这只发生在 UITextView 的最底部。如果现有的两个段落正常出现,我决定在现有的两个段落之间输入一个段落,则不会出现光标消失的问题。
我已经包含了下面的代码,但我很困惑是什么导致了这个问题。
import Foundation
import UIKit
import CoreData
class textViewTableViewCell: UITableViewCell, UITextViewDelegate {
//
var tableView: UITableView? {
var view = self.superview
while (view != nil && view!.isKind(of: UITableView.self) == false) {
view = view!.superview
}
return view as? UITableView
}
public var cellText: String = ""
var peopleArray: [NSManagedObject] = []
@IBOutlet weak var textView: UITextView!
override func layoutSubviews() {
textView.delegate = self
//textView.text = cellText
}
func textViewDidChange(_ textView: UITextView) {
save()
}
func save() {
let offset = textView.contentOffset
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
// 1
let managedContext =
appDelegate.persistentContainer.viewContext
// 2
let entity =
NSEntityDescription.entity(forEntityName: "Person",
in: managedContext)!
let person = NSManagedObject(entity: entity,
insertInto: managedContext)
//2.5
let predicate = NSPredicate(format: "name == %@", cellText)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
fetchRequest.predicate = predicate
do {
let fetchedEntities = try managedContext.fetch(fetchRequest) as! [Person]
fetchedEntities.first?.name = textView.text
cellText = textView.text
} catch {
// Do something in response to error condition
}
do {
try managedContext.save()
tableView?.beginUpdates()
tableView?.endUpdates()
} catch {
// Do something in response to error condition
}
}
}
class JournalEntryDetailViewController: UITableViewController, UITextViewDelegate {
public var hasViewAppeared: Bool = false
public var text: String = ""
var people: [NSManagedObject] = []
//@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
tableView.estimatedRowHeight = 500
tableView.rowHeight = UITableViewAutomaticDimension
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func viewWillAppear(_ animated: Bool) {
//when the journal entry view is about to appear, we do not want the iOS 10 added large titles
//https://chariotsolutions.com/blog/post/large-titles-ios-11/
self.navigationController?.navigationBar.prefersLargeTitles = false
}
override func viewDidAppear(_ animated: Bool) {
hasViewAppeared = true
tableView.reloadData()
//tableView.beginUpdates()
//tableView.endUpdates()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.destination is ViewController
{
let vc = segue.destination as? ViewController
vc?.removeBlanks()
vc?.tableView.reloadData()
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: textViewTableViewCell = tableView.dequeueReusableCell(withIdentifier: "textCell",
for: indexPath) as! textViewTableViewCell
cell.cellText = text
cell.textView.text = text
cell.peopleArray = people
return cell
}
}
修复了错误,但不是最令人满意的解决方案。由于某种原因
tableView?.beginUpdates()
tableView?.endUpdates()
需要运行两次。
tableView?.beginUpdates()
tableView?.endUpdates()
tableView?.beginUpdates()
tableView?.endUpdates()
不知道为什么?第一个循环更新只更新 UITableViewCell 的高度,然后第二个循环更新 UITextView。奇怪...如果有人能解释为什么我会接受他们的答案。
我在 UITableViewCell 中嵌入了一个 UITextView。
在更新 UITextView 时调用 reloadTableView() 实现 UITableViewCell 在 UITextView 变得太大或太小时自动调整大小。
问题是当通过为前一行创建一个太大的单词或按 return 移动到一个全新的行时,光标不会立即出现。相反,光标将消失并且应该在新行上的字符或单词无法看到,直到添加了一个额外的字符,此时它才应该出现。你可以在 giphy 上的 gif link 中看到问题: gif image of problem
值得注意的是,这只发生在 UITextView 的最底部。如果现有的两个段落正常出现,我决定在现有的两个段落之间输入一个段落,则不会出现光标消失的问题。
我已经包含了下面的代码,但我很困惑是什么导致了这个问题。
import Foundation
import UIKit
import CoreData
class textViewTableViewCell: UITableViewCell, UITextViewDelegate {
//
var tableView: UITableView? {
var view = self.superview
while (view != nil && view!.isKind(of: UITableView.self) == false) {
view = view!.superview
}
return view as? UITableView
}
public var cellText: String = ""
var peopleArray: [NSManagedObject] = []
@IBOutlet weak var textView: UITextView!
override func layoutSubviews() {
textView.delegate = self
//textView.text = cellText
}
func textViewDidChange(_ textView: UITextView) {
save()
}
func save() {
let offset = textView.contentOffset
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
// 1
let managedContext =
appDelegate.persistentContainer.viewContext
// 2
let entity =
NSEntityDescription.entity(forEntityName: "Person",
in: managedContext)!
let person = NSManagedObject(entity: entity,
insertInto: managedContext)
//2.5
let predicate = NSPredicate(format: "name == %@", cellText)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")
fetchRequest.predicate = predicate
do {
let fetchedEntities = try managedContext.fetch(fetchRequest) as! [Person]
fetchedEntities.first?.name = textView.text
cellText = textView.text
} catch {
// Do something in response to error condition
}
do {
try managedContext.save()
tableView?.beginUpdates()
tableView?.endUpdates()
} catch {
// Do something in response to error condition
}
}
}
class JournalEntryDetailViewController: UITableViewController, UITextViewDelegate {
public var hasViewAppeared: Bool = false
public var text: String = ""
var people: [NSManagedObject] = []
//@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
tableView.estimatedRowHeight = 500
tableView.rowHeight = UITableViewAutomaticDimension
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func viewWillAppear(_ animated: Bool) {
//when the journal entry view is about to appear, we do not want the iOS 10 added large titles
//https://chariotsolutions.com/blog/post/large-titles-ios-11/
self.navigationController?.navigationBar.prefersLargeTitles = false
}
override func viewDidAppear(_ animated: Bool) {
hasViewAppeared = true
tableView.reloadData()
//tableView.beginUpdates()
//tableView.endUpdates()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.destination is ViewController
{
let vc = segue.destination as? ViewController
vc?.removeBlanks()
vc?.tableView.reloadData()
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: textViewTableViewCell = tableView.dequeueReusableCell(withIdentifier: "textCell",
for: indexPath) as! textViewTableViewCell
cell.cellText = text
cell.textView.text = text
cell.peopleArray = people
return cell
}
}
修复了错误,但不是最令人满意的解决方案。由于某种原因
tableView?.beginUpdates()
tableView?.endUpdates()
需要运行两次。
tableView?.beginUpdates()
tableView?.endUpdates()
tableView?.beginUpdates()
tableView?.endUpdates()
不知道为什么?第一个循环更新只更新 UITableViewCell 的高度,然后第二个循环更新 UITextView。奇怪...如果有人能解释为什么我会接受他们的答案。