質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

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

Swift

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

Q&A

解決済

1回答

1890閲覧

テーブルビューのセルの高さの自動調整について

sw07

総合スコア22

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/10/22 02:38

編集2018/10/23 02:17

お世話になります。
Swift初心者です。

お忙しい中大変申し訳ございませんが、
現在、UITableViewの実装で悩んでおります。

セルの高さの自動調整についてのご質問となります。

前提・実現したいこと

セルの構成として、
セルの左半分にLabel、右半分にTextViewを配置し、
Labelのテキストは可変長(テキスト長に応じて高さが変動)、TextViewの高さは固定(高さ:300)として、
・Labelのテキスト長が少ない(Labelの高さ<TextViewの高さ)の場合 → セルの高さをTextViewの高さとする
・Labelのテキスト長が多い(Labelの高さ>TextViewの高さ)の場合 → セルの高さをLabelの高さとする
を考えております。

発生している問題・エラーメッセージ

書籍やWebより、
セルの高さの自動調整として、

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { freeSetsumon.estimatedRowHeight = 150 return UITableViewAutomaticDimension }

の処理で高さが自動で算出され、
かつ、その際、LabelもしくはTextViewのいずれかに制限をかけなければならないというのは
何となくわかってきてはいるのですが、実装上どのようにすれば上記が実現できるのかがわからず
困っている状況でございます。

実装方法について、ご存知の方がおりましたら、
ご助力を賜りたく、ご教授頂けますと幸いでございます。

ご迷惑をおかけ
どうぞ、よろしくお願い致します。

該当のソースコード

▼Label側(Viewの中にLabelを配置) Labelはstoryboard上でLines=0としております // View include Label labelBaseView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ labelBaseView.widthAnchor.constraint(equalToConstant: 400.0), labelBaseView.topAnchor.constraint(equalTo: cell.topAnchor, constant: 5.0), labelBaseView.leadingAnchor.constraint(equalTo: cell.leadingAnchor, constant: 10.0), labelBaseView.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: 0.0) ]) // Label labelName.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ labelName.topAnchor.constraint(equalTo: labelBaseView.topAnchor, constant: 0.0), labelName.leadingAnchor.constraint(equalTo: labelBaseView.leadingAnchor, constant: 0.0), labelName.trailingAnchor.constraint(equalTo: labelBaseView.trailingAnchor, constant: 0.0), labelName.bottomAnchor.constraint(equalTo: labelBaseView.bottomAnchor, constant: 0.0) ]) ▼TextView側(Viewの中にTextViewを配置) // View include TextView textBaseView.translatesAutoresizingMaskIntoConstraints = false textBaseView.heightAnchor.constraint(equalToConstant: 300.0).isActive = true textBaseView.topAnchor.constraint(equalTo: cell.topAnchor, constant: 10.0).isActive = true textBaseView.leadingAnchor.constraint(equalTo: labelBaseView.trailingAnchor, constant: 8.0).isActive = true textBaseView.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: -10.0).isActive = true if labelHeight < 300.0 { inputBaseView.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: -10.0).isActive = true } // TextView textView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ textView.topAnchor.constraint(equalTo: textBaseView.topAnchor), textView.bottomAnchor.constraint(equalTo: textBaseView.bottomAnchor), textView.leadingAnchor.constraint(equalTo: textBaseView.leadingAnchor), textView.trailingAnchor.constraint(equalTo: textBaseView.trailingAnchor) ]) ▼実行箇所 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! sampleTableViewCell cell.labelName.text = "1234567890" ★ここでLabel側の制約処理を実行しています return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { sampleTableView.estimatedRowHeight = 150 return UITableViewAutomaticDimension } func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { tableView.beginUpdates() ★ここでTextView側の制約処理を実行しています tableView.estimatedRowHeight = 150 tableView.rowHeight = UITableViewAutomaticDimension tableView.endUpdates() }

試したこと

補足情報(FW/ツールのバージョンなど)

Swift4
xCode10.0

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

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

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

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

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

fuzzball

2018/10/22 04:10

現在、どういう制約を付けているか教えて下さい。
sw07

2018/10/22 05:12

ご連絡頂き、ありがとうございます。「該当のソースコード」へ現在つけている制約を追記させて頂きました。ご確認頂けますと幸いです。
sw07

2018/10/22 05:19

ご説明が不足しておりまして、申し訳ございません。Labelの自動調整後の高さをどのタイミングで取得すれば、TextViewとの高さ判定に使えるのかわからず悩んでおります。
fuzzball

2018/10/23 01:49

3つ質問します。inputBaseViewというのは何でしょうか?各Viewの階層を教えて下さい。このコードはどこで実行していますか?
sw07

2018/10/23 02:18

「inputBaseView」は「textBaseView」の誤りでした。記載を修正いたしました
sw07

2018/10/23 02:19

階層はセルの中にViewを左右に2つ並べ、左のビューの中にLabel、右のビューの中にTextViewを配置する構成となります。
sw07

2018/10/23 02:21

各制約処理の実行箇所につきまして、追記させて頂きました。お手数をおかけ致しまして申し訳ございませんが、ご確認頂けますと幸いです。よろしくお願い致します。
guest

回答1

0

ベストアンサー

swift

1if labelHeight < 300.0 { 2 inputBaseView.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: -10.0).isActive = true 3}

の代わりに、

swift

1let bottom = textBaseView.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: -10.0) 2bottom.priority = UILayoutPriority(rawValue: labelName.contentCompressionResistancePriority(for: .vertical).rawValue - 1) 3bottom.isActive = true

これでどうでしょうか?
Labelの縦に伸びる力(?)よりもTextViewのbottom制約の優先を下げています。

ちなみに

tableView(_:willDisplay:forRowAt:)の処理は不要です。

また、tableView(_:heightForRowAt:)も不要です。
こっちは、書くとすれば、

swift

1func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 2 return UITableViewAutomaticDimension 3} 4func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { 5 return 150 6}

となります。

さらに

制約を付けるのは一度だけでいいので、sampleTableViewCellの`awakeFromNib()にでも書くのがいいと思います。

投稿2018/10/23 02:56

編集2018/10/23 03:52
fuzzball

総合スコア16731

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

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

fuzzball

2018/10/23 03:00 編集

補足ですが、セルにViewを乗せるときは、cellに直接乗せるのではなくcell.contentViewに乗せます。乗せたViewの制約もcell.contentViewに対して付けます。 こちらではcell.contentViewに乗せて試しましたので、もしうまくいかない場合は、contentViewにViewを乗せるように修正して下さい。(今のままでうまくいったとしても修正をお勧めしますが)
sw07

2018/10/24 05:36

解決できました! UILayoutPriorityで制約に優先順位をつけることで解決できるとは考えもおよばず。。 大変勉強になりました! スムーズかつわかりやすいご回答、誠にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問