Zac*_*117 4 uitableview ios swift
我已经编写了自己的函数来在键盘出现时向上滚动文本字段。为了通过点击远离文本字段来关闭键盘,我创建了一个 UITapGestureRecognizer,它负责在点击离开时退出文本字段上的第一响应者。
但是,在选择自动完成表中的一个条目时,DidselectRoyatIndexpath也不会被调用。相反,似乎点击手势识别器正在被调用并且只是让第一响应者辞职。
我猜有一些方法可以告诉点击手势识别器继续将点击消息传递给 UITableView,但我不知道它是什么。在 objc 和 9 多年前关于堆栈溢出的帖子和帖子中只有解决方案,我想知道是否有更新的解决方案!谢谢,如果您想看看发生了什么,这是我的代码:
class ChatLogController : UIViewController, UITextFieldDelegate , UITableViewDelegate , UITableViewDataSource, UIGestureRecognizerDelegate, UIImagePickerControllerDelegate ,UINavigationControllerDelegate {
var messages = [Message]()
var user : User?{
didSet{
observeMessages()
}
}
@IBOutlet weak var tabelView: UITableView!
@IBOutlet weak var messageTextField: UITextField!
@IBOutlet weak var bottomViewHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var currentMessageRecieverImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
configureTableView()
currentMessageRecieverImage.translatesAutoresizingMaskIntoConstraints = false;
currentMessageRecieverImage.layer.cornerRadius = 30;
currentMessageRecieverImage.layer.masksToBounds = true
currentMessageRecieverImage.contentMode = .scaleAspectFill
if let currentMessageRecieverUser = user{
currentMessageRecieverImage.loadImageUsingCacheWithUrlString(urlString: currentMessageRecieverUser.picURL!);
print(currentMessageRecieverUser.userName!)
}
tabelView.delegate = self;
tabelView.dataSource = self;
messageTextField.delegate = self;
let dragAwayFromTextGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleTapAwayFromTextEdit))
dragAwayFromTextGesture.direction = UISwipeGestureRecognizerDirection.down
dragAwayFromTextGesture.delegate = self;
tabelView.addGestureRecognizer(dragAwayFromTextGesture)
let dragBackToMessages = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeBackToMessages))
dragBackToMessages.direction = UISwipeGestureRecognizerDirection.right
dragBackToMessages.delegate = self;
tabelView.addGestureRecognizer(dragBackToMessages)
let TapAwayFromTextEditTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapAwayFromTextEdit))
tabelView.addGestureRecognizer(TapAwayFromTextEditTapGesture)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
@objc func handleSwipeBackToMessages(){
dismiss(animated: false, completion: nil)
}
func observeMessages(){
guard let uid = Auth.auth().currentUser?.uid else{
return;
}
// ref gets user that is logged in
let ref = Database.database().reference().child("user-messages").child(uid)
ref.observe(.childAdded) { (snapshot) in
// gets needed messages
let messageId = snapshot.key
let messagesRef = Database.database().reference().child("messages").child(messageId)
messagesRef.observe(.value, with: { (snapshot) in
guard let dict = snapshot.value as? [String : AnyObject] else{
return
}
let message = Message()
message.imageUrl = dict["imageurl"] as? String
message.fromId = dict["fromid"] as? String
message.text = dict["text"] as? String
message.timestamp = dict["timestamp"] as? String
message.toId = dict["toid"] as? String
if message.chatPartnerId() == self.user?.toId{
self.messages.append(message)
}
DispatchQueue.main.async {
self.tabelView.reloadData()
}
})
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellid" , for: indexPath) as! CustomChatTableViewCell;
let gray = UIColor(red:0.94, green:0.94, blue:0.94, alpha:1.0)
let red = UIColor(red:1.00, green:0.22, blue:0.37, alpha:1.0)
let message = messages[indexPath.item]
if message.toId == user?.toId{
cell.messageBackground.backgroundColor = red
cell.messageLabel.textColor = UIColor.white
}
else{
cell.messageBackground.backgroundColor = gray
cell.messageLabel.textColor = UIColor.black
}
cell.messageLabel.text = message.text
if message.imageUrl != nil{
//print(message.imageUrl!)
// cell.messageImageView.image = UIImage(named : "user.jpg")
cell.messageImageView.loadImageUsingCacheWithUrlString(urlString: message.imageUrl!)
//print(cell.messageImageView.image.debugDescription)
cell.messageImageView.isHidden = false;
cell.messageImageView.translatesAutoresizingMaskIntoConstraints = false;
cell.messageImageView.contentMode = .scaleAspectFill
cell.messageLabel.isHidden = true
cell.messageBackground.isHidden = true;
}
else
{
cell.messageImageView.isHidden = true;
cell.selectionStyle = UITableViewCellSelectionStyle.none
cell.messageLabel.isHidden = false
cell.messageBackground.isHidden = false;
}
return cell;
}
@objc func handleTapAwayFromTextEdit(){
//print("handle tap away from text edit running ")
messageTextField.endEditing(true)
}
@IBAction func backToMessageListPressed(_ sender: Any) {
dismiss(animated: false, completion: nil)
}
@IBAction func infoButtonPressed(_ sender: Any) {
}
// saves text to fire base
@IBAction func sendButtonPressed(_ sender: Any) {
handleSendMessageToDataBase()
}
func handleSendMessageToDataBase(){
let ref = Database.database().reference().child("messages")
// needed for making list in firebase for unique texts
let childRef = ref.childByAutoId()
if messageTextField.text == ""{
return
}
if let message = messageTextField.text{
let toID = user!.toId!
let fromId = Auth.auth().currentUser!.uid
let timeStamp : Int = Int(Int(NSDate().timeIntervalSince1970))
print(timeStamp)
let values = ["text" : message , "toid" : toID , "timestamp" : "\(timeStamp)" , "fromid" : fromId]
childRef.updateChildValues(values, withCompletionBlock: { (error, ref) in
if error != nil{
print(error!)
return
}
let userMessagesref = Database.database().reference().child("user-messages").child(fromId)
let messageID = childRef.key
userMessagesref.updateChildValues([messageID: 1])
let recipientUserMessageRef = Database.database().reference().child("user-messages").child(toID)
recipientUserMessageRef.updateChildValues([messageID: 1])
})
}
messageTextField.text = ""
messageTextField.endEditing(true)
}
@IBAction func sendImageButtonPressed(_ sender: Any) {
handleSendImage()
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
print("You selected cell #\(indexPath.row)!")
}
func handleSendImage(){
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker : UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage{
selectedImageFromPicker = editedImage
}
else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage{
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker{
uploadToFireBaseUsingSelectedImage(selectedImage : selectedImage)
}
dismiss(animated: true, completion: nil)
}
private func uploadToFireBaseUsingSelectedImage(selectedImage :
UIImage){
let imageName = NSUUID().uuidString
let refToStorage = Storage.storage().reference().child("message_images").child(imageName)
if let uploadData = UIImageJPEGRepresentation(selectedImage, 0.2){
refToStorage.putData(uploadData, metadata: nil, completion: { (metaData, error) in
if error != nil{
print("failed to upload firebase image when sending in chatlogcontroller")
print(error!)
return
}
if let imageURL = metaData?.downloadURL()?.absoluteString{
self.sendMessageWithImageURL(imageURL: imageURL)
}
})
}
}
private func sendMessageWithImageURL(imageURL : String){
let ref = Database.database().reference().child("messages")
// needed for making list in firebase for unique texts
let childRef = ref.childByAutoId()
let toID = user!.toId!
let fromId = Auth.auth().currentUser!.uid
let timeStamp : Int = Int(Int(NSDate().timeIntervalSince1970))
print(timeStamp)
let values = ["imageurl" : imageURL , "toid" : toID , "timestamp" : "\(timeStamp)" , "fromid" : fromId]
childRef.updateChildValues(values, withCompletionBlock: { (error, ref) in
if error != nil{
print(error!)
return
}
let userMessagesref = Database.database().reference().child("user-messages").child(fromId)
let messageID = childRef.key
userMessagesref.updateChildValues([messageID: 1])
let recipientUserMessageRef = Database.database().reference().child("user-messages").child(toID)
recipientUserMessageRef.updateChildValues([messageID: 1])
})
}
func textFieldDidBeginEditing(_ textField: UITextField) {
UIView.animate(withDuration: 0.2, animations:{
self.bottomViewHeightConstraint.constant = 308;
self.view.layoutIfNeeded()
})
}
func textFieldDidEndEditing(_ textField: UITextField) {
UIView.animate(withDuration: 0.2, animations:{
self.bottomViewHeightConstraint.constant = 50;
self.view.layoutIfNeeded()
})
}
func configureTableView()
{
tabelView.delegate = self;
tabelView.dataSource = self;
tabelView.register(UINib(nibName: "MessageCell" , bundle : nil), forCellReuseIdentifier: "customMessageCell");
tabelView.allowsSelection = true;
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self);
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let message = messages[indexPath.item]
if message.imageUrl != nil{
return 200
}
return (CGFloat((message.text?.count)! + 70) )
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
handleSendMessageToDataBase()
return true
}
Run Code Online (Sandbox Code Playgroud)
}