🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2025閲覧

【Swift】tableView Cellに画像を表示すると、セルとセルの間が大きく空いてしまう問題を解決したい

Yuya_Kimura

総合スコア11

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/11/19 06:18

編集2019/11/22 04:20

実現したいこと

画像とテキストの送信が可能なチャットアプリを作っています。LINEのように、画像を送信してもテキストを送信しても、バブル(セル)間の間隔が均等になるようにしたいです。具体的には、セルとセルの間は8ptで作成したいです。

###今の問題点
テキストを送信した時はセルとセルの間が設定した通りの間隔で空いてくれるが、画像を送信した時はセルとセルの間が非常に大きく空いてしまう。

テキストを送信した時のセルとセルの間の間隔
テキストを送信した時のセルとセルの間の間隔

画像を送信した時のセルとセルの間の間隔
イメージ説明

##現状の実装

画像用のセルの詳細
イメージ説明

テキスト表示用のセルの詳細
イメージ説明

画像やテキストをFirebaseのDBにアップロードする部分のコード

Swift

1func retrieveMessages () { 2 3 let messagesDB = messageRef.child(userID!).child(chatMateInfo.uid).child("Messages") 4 messagesDB.observe(.childAdded) { (snapshot) in 5 6 guard let snapshotValue = snapshot.value as? Dictionary<String, String> else { return } 7 8 let dateStr = snapshotValue["date"]! 9 let formatter: DateFormatter = DateFormatter() 10 formatter.locale = Locale(identifier: "ja_JP") 11 formatter.dateFormat = "yyyy/MM/dd HH:mm:ss" 12 let formattedDate = formatter.date(from: dateStr)! 13 14 let message = MessageBox(senderUid: snapshotValue["senderUid"]!, date: formattedDate) 15 if let text = snapshotValue["text"] { 16 message.text = text 17 } else { 18 message.imageURL = snapshotValue["imageURL"]! 19 } 20 self.messageBox.append(message) 21 self.messageTableView.reloadData() 22 23 let bottomRow = NSIndexPath(row: (self.messageBox.count - 1), section: 0) 24 self.messageTableView.scrollToRow(at: 25 bottomRow as IndexPath, at: UITableView.ScrollPosition.bottom, animated: true) 26 } 27 }

セルの内容を決める部分のコード

Swift

1func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 2 3 // 送信された時間に応じてソート 4 let sortedMessages = messageBox.sorted { (recentMessage: MessageBox, pastMessage: MessageBox) -> Bool in 5 pastMessage.date > recentMessage.date 6 } 7 let senderUid = sortedMessages[indexPath.row].senderUid 8 // テキストメッセージの場合 9 if let text = sortedMessages[indexPath.row].text { 10 let cell = tableView.dequeueReusableCell(withIdentifier: "chatCell", for: indexPath) as! ChatCell 11 cell.chatTextView.text = text 12 13 if senderUid == Auth.auth().currentUser?.uid { 14 cell.chatTextBubble.backgroundColor = UIColor.init(red: 250/255, green: 120/255, blue: 160/255, alpha: 1) 15 cell.chatStackView.alignment = .trailing 16 } else { 17 cell.chatTextBubble.backgroundColor = UIColor.init(red: 141/255, green: 226/255, blue: 213/255, alpha: 1) 18 cell.chatStackView.alignment = .leading 19 } 20 return cell 21 // 画像メッセージの場合 22 } else { 23 let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath) as! ImageCell 24 25 cell.chatImageView.contentMode = UIImageView.ContentMode.scaleAspectFit 26 cell.chatImageView?.sd_setShowActivityIndicatorView(true) 27 cell.chatImageView?.sd_setIndicatorStyle(.gray) 28 let typeChangedImageURL = URL(string: sortedMessages[indexPath.row].imageURL! ) 29 cell.chatImageView.sd_setImage(with: typeChangedImageURL) 30 if senderUid == Auth.auth().currentUser?.uid { 31 cell.imageStackView.alignment = .trailing 32 } else { 33 cell.imageStackView.alignment = .leading 34 } 35 36 return cell 37 } 38 }

###【追記】VIewのヒエラルキーとセルの大きさ
セルの背景色以下のようにピンク色に変えました
イメージ説明

チャット画面のスクリーンショットです。セルが大きくなってしまっているようです
イメージ説明

ヒエラルキーです
イメージ説明

###【追記】heightForRowAtを試しました
このように書くか

Swift

1func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 2 messageTableView.estimatedRowHeight = 130 3 return UITableView.automaticDimension 4 }

このように書いてviewDidLoadとメッセージ取得のメソッドの中に書く

Swift

1func fixCellSize() { 2 messageTableView.rowHeight = UITableView.automaticDimension 3 messageTableView.estimatedRowHeight = 130 4 }

上記2つのパターンを試しましたが、どちらも立ち上げた瞬間はこのように表示されるのですが
イメージ説明

下にスクロールする、もしくは新規のテキストメッセージを送信すると
また元のように画像のセルだけが大きくなってしまいます。
イメージ説明

###その他の情報
開発環境:
Xcode 10.1
Swift 4.2.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yuya_Kimura

2019/11/20 03:41

コメントくださりありがとうございます。 対応いたしますので、少々お待ちください。
isaoeka

2019/11/20 03:41

ありがとうございます!
Yuya_Kimura

2019/11/20 03:59

質問の下部に情報を追加させていただきました。 お手すきの際にご確認いただけますと幸いです!
Yuya_Kimura

2019/11/20 12:32

コメントくださりありがとうございます。AutoLayoutを設定したのみで このメソッドは使用していませんでした。実装してビルドして、また結果を共有させていただきます!
Yuya_Kimura

2019/11/22 04:13

すみません、上記のコメントはミスです。 行ったことを追記しました。 heightForRowAtを行っても、スクロール、あるいは新しいテキストメッセージを送信すると また元のようにセルのサイズが大きくなってしまいます(画像を表示するセルの時のみ) cellのreUseなどが関係しているのでしょうか?
MasatoUchida

2019/11/22 08:45

estimatedRowHeightを設定する場合は`tableView:estimatedHeightForRowAtIndexPath:`です。 一度UITableViewDelegateの公式ドキュメント(英語ですが)読んでみた方がいいかと思います。 クリティカルな答えが出せなくて申し訳ないです。
Yuya_Kimura

2019/11/22 11:30

すみません、ご丁寧にありがとうございます。細かい部分の書き違えなどご指摘いただき非常に助かります。 まずはちゃんと目を通してみます!
eytyet

2019/11/23 05:48

`tableView(:heightForRowAt)`で100などの固定値を返せば制限はできます。この数字を工夫してなんとかするというのは一つの方法です。 でも、自動できちんと表示されるようにできた方が楽で便利です。 自動にしているのに大きくなる原因は、ヒエラルキーの画像を見る限り、画像が上下にとても長い大きさだからです。imageCellの中のUIImageViewの制約を確認してみるとよいと思います。
Yuya_Kimura

2019/11/23 10:04

画像の制約への観点がなかったです。非常に助かります。 ありがとうございます!!
Yuya_Kimura

2019/11/25 13:22

みなさん、ご回答いただきありがとうございました。 どれも学びになるものばかりで大変助かりました。
guest

回答1

0

自己解決

みなさん、アドバイスをくださり本当にありがとうございました。
以下のように、画像を取得する際にライブラリのメソッドを使ってリサイズすることでちょうど良いサイズで表示できるようになりました。ありがとうございました!

Swift

1cell.chatImageView.contentMode = UIImageView.ContentMode.scaleAspectFit 2 cell.chatImageView?.sd_imageIndicator = SDWebImageActivityIndicator.gray; 3 let transformer = SDImageResizingTransformer(size: CGSize(width: 70, height: 70), scaleMode: .fill) 4 let typeChangedImageURL = URL(string: sortedMessages[indexPath.row].imageURL! ) 5 cell.chatImageView.sd_setImage(with: typeChangedImageURL, placeholderImage: nil, context: [.imageTransformer: transformer])

投稿2019/11/25 06:46

Yuya_Kimura

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問