Я начинаю создавать приложение чата и хочу, чтобы оно прокручивалось до самого низа при каждом вводе текста или изображения.Для текста код идеально подходит для выполнения scrollToRow после перезагрузки tableView.Тем не менее, изображение всегда отображается под клавиатурой , я пробовал много способов решить эту проблему, но все равно получил тот же результат. изображение не отображается над клавиатурой изображение находится под клавиатурой
class ChatTableViewController: UITableViewController, UITextViewDelegate {
private let reuseIdentifier = "reuseIdentifier"
private let chatImageIdentifier = "chatImageCell"
var sSection = 0
var rRow = 0
var commentRef: DatabaseReference!
var firebaseHandle: DatabaseHandle?
var dataSnapshot: DataSnapshot?
let uid = FirebaseHelper.shared.getUserId()
let username = FirebaseHelper.shared.getUsername()
let email = FirebaseHelper.shared.getUserEmail()
var comments = [Comment]()
var intArray: [Int]? {
didSet{
guard let intArray = intArray else {return}
self.sSection = intArray[0]
self.rRow = intArray[1]
commentRef = FirebaseHelper.shared.getCommentRef(firebaseRef: .comments, section: sSection, row: rRow)
comments = []
tableView.reloadData()
observeCommentsFromFirebase {
}
setUpKeyboardObserver()
}
}
func observeCommentsFromFirebase(completion: @escaping (()->Void)) {
firebaseHandle = commentRef.queryOrdered(byChild: "timeStamp").observe(.childAdded, with: { (snapshot) in
self.dataSnapshot = snapshot
if let dictionary = snapshot.value as? [String: Any]{
let comment = Comment(dictionary: dictionary)
self.comments.append(comment)
DispatchQueue.main.async {
self.tableView.reloadData()
self.handleKeyboardDidShow()
completion()
}
}
}, withCancel: nil)
}
func setUpKeyboardObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardDidShow), name: UIResponder.keyboardDidShowNotification, object: nil)
}
@objc func handleKeyboardDidShow() {
if comments.count > 0 {
let indexPath = IndexPath(row: comments.count - 1, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(ChatTableViewCell.self, forCellReuseIdentifier: reuseIdentifier)
tableView.register(ChatImageCell.self, forCellReuseIdentifier: chatImageIdentifier)
tableView.separatorStyle = .none
tableView.allowsSelection = false
tableView.backgroundColor = grayColor
tableView.keyboardDismissMode = .interactive
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(handleDismiss))
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
tableView.alwaysBounceVertical = true
}
@objc func handleDismiss() {
if let firebaseHandle = firebaseHandle {
self.commentRef.removeObserver(withHandle: firebaseHandle)
}
NotificationCenter.default.removeObserver(self)
self.dismiss(animated: true, completion: nil)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let comment = comments[indexPath.row]
if comment.imageUrl != "" {
let cell = tableView.dequeueReusableCell(withIdentifier: chatImageIdentifier, for: indexPath) as! ChatImageCell
if comments.count != 0 {
cell.comment = comment
}
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! ChatTableViewCell
if comments.count != 0 {
cell.comment = comment
}
return cell
}
}
@objc func uploadImage() {
showImageActionSheet()
}
extension ChatTableViewController: UINavigationControllerDelegate, UIImagePickerControllerDelegate {
func showImageActionSheet() {
// declaring action sheet
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
// declaring camera button
let camera = UIAlertAction(title: "Camera", style: .default) { (action) in
// if there is camera, then execute
if UIImagePickerController.isSourceTypeAvailable(.camera) {
self.showPicker(with: .camera)
}
}
// declaring library button
let library = UIAlertAction(title: "Library", style: .default) { (action) in
// if there is library, then execute
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
self.showPicker(with: .photoLibrary)
}
}
// declaring cancel button
let cancel = UIAlertAction(title: "Cancel", style: .cancel)
// add action to the sheet
alertController.addAction(camera)
alertController.addAction(library)
alertController.addAction(cancel)
// present action sheet to the user
self.present(alertController, animated: true, completion: nil)
}
func showPicker(with source: UIImagePickerController.SourceType) {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
picker.sourceType = source
self.present(picker, animated: true, completion: nil)
}
// fetch selected image from info with key
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
var selectedImage: UIImage?
// declaring editedImage
if let editedImage = info[.editedImage] as? UIImage {
selectedImage = editedImage
} else if let originalImage = info[.originalImage] as? UIImage {
selectedImage = originalImage
}
self.dismiss(animated: true, completion: nil)
FirebaseHelper.shared.uploadImage(image: selectedImage, firebaseRef: .comment_images, viewController: self) {
urlString in
let timeStamp = Helper.shared.dateOfCurrentTimeZone()
let childKey = FirebaseHelper.shared.getChildKey()
let profileImageUrlString: String
if let profileImageUrl = FirebaseHelper.shared.getPhotUrl() {
profileImageUrlString = profileImageUrl.absoluteString
} else {
profileImageUrlString = ""
}
let values: [String: Any] = ["text": "", "uid": self.uid, "timeStamp": timeStamp, "childkey": childKey, "username": self.username, "email": self.email ?? "", "imageUrl": urlString, "profileImageUrl": profileImageUrlString]
self.commentRef.child(childKey).updateChildValues(values, withCompletionBlock: { (error, dataRef) in
if error != nil {
Helper.shared.alertController(title: "Error", message: error!.localizedDescription, viewController: self)
return
}
})
}
}
}