やあみんな私は迅速にかなり新しいので親切にしてください!キーボードが表示されたときにテキストフィールドを上にスクロールする独自の関数を作成しました。テキストフィールドからタップしてキーボードを閉じるために、タップしたときにテキストフィールドのファーストレスポンダーを辞任するUITapGestureRecognizerを作成しました。
ただし、自動完了テーブルのエントリの1つを選択すると、didSelectRowAtIndexPathは呼び出されません。代わりに、タップジェスチャレコグナイザーが呼び出され、ファーストレスポンダーを辞任したようです。
タップジェスチャレコグナイザーにタップメッセージを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
}
}
解決策は、のプロパティをに設定cancelsTouchesInView
するTapAwayFromTextEditTapGesture
ことfalse
です。これにより、テーブルビューへのタッチが渡されます。
このプロパティに関するAppleのドキュメントから(私の強調で):
このプロパティがtrue(デフォルト)で、受信者がそのジェスチャを認識すると、保留中のジェスチャのタッチはビューに配信されず、以前に配信されたタッチは、ビューに送信されたtouchesCancelled(_:with :)メッセージによってキャンセルされます。 。ジェスチャ認識機能がジェスチャを認識しない場合、またはこのプロパティの値がfalseの場合、ビューはマルチタッチシーケンスのすべてのタッチを受け取ります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加