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

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

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

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

Swift

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

Q&A

解決済

1回答

3060閲覧

UITableViewの高さを可変、UITableView内の画像の幅を固定、UITableView内の文字を折り返しにしたい。

Risney

総合スコア148

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/08/17 14:22

編集2020/08/19 13:55

前提・実現したいこと

以前の質問で作成したUITableViewに以下の3つの機能を実装したいです。(※コード全容は記事下部にあります)
・UITableView内のテキストを折り返しにしたい。
・UITableViewの高さをテキストの多さによって可変
・UITableView内のImageViewの幅を固定してAspectFitにしたい
(※折り返しにして文字の高さによってUITableViewが可変になるが画像サイズはそのまま。というイメージ)

現状、ラベルは三点リーダで省略されてしまう。
イメージ説明

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

######問題点①TableView内のテキストを折り返ししようとすると、UIが崩れる

文字を折り返しをするために
こちらのサイトを参考に以下のコードを追加したところ

swift

1cell.textLabel?.numberOfLines=0

画像がどっかーんってなりました。

イメージ説明

でも文字はちゃんと縦になっているので、
改行はされていると思われます。

######問題点②TableView内のimageViewが制御できない。

問題点①はおそらく
「UITableView内のImageViewの高さと幅が固定されていないからだな」
と思ったので、こちらのサイトを参考に以下のコードを「cellForRowAt indexPath」に追加

@IBOutlet weak var image: UIImageView! --省略-- image.frame = CGRect(x: 0, y: 0, width: 50, height: 50)

すると以下のエラーコード

error

1The image outlet from the ViewController to the UIImageView is invalid. Outlets cannot be connected to repeating content. [12] 2 3和約:ViewControllerからUIImageViewへの画像アウトレットが無効です。 コンセントを繰り返しコンテンツに接続することはできません。 [12]

繰り返し…?
TableViewを繋げているから、
その中のImgeviewを繋げようとして怒られるのでしょうか…?

TableView内のImageViewをOutlet接続以外で制御する方法を知りたいです。

######問題点③セルの可変

こちらのサイトを参考に以下のコードを追加したいのですが、問題点①と②の影響で、正しいのかどうかを確認できず。

一旦これをなくしたら画像が大きくならないのかを確認してみようと思います。

swift

1commentTableView.estimatedRowHeight = 66 2commentTableView.rowHeight = UITableViewAutomaticDimension

該当のソースコード

swift

1import UIKit 2 3struct HogeItem: Decodable { 4 let Name: String 5 let Image: String 6} 7 8struct HogeSection: Decodable { 9 let SectionName: String 10 let Items: [HogeItem] 11} 12 13var _items: [HogeSection] = [] 14 15class ViewController: UIViewController,UITableViewDelegate, UITableViewDataSource { 16 // MARK: - pattern②Plistあり 17 @IBOutlet weak var commentTableView: UITableView! 18 @IBOutlet weak var image: UIImageView! 19 20 override func viewDidLoad() { 21 super.viewDidLoad() 22 23 if let path = Bundle.main.path(forResource: "DisneyCharacterList", ofType:"plist" ) { 24 let data = try! Data(contentsOf: URL(fileURLWithPath: path)) 25 _items = try! PropertyListDecoder().decode([HogeSection].self, from: data) 26 } 27 28 //高さを可変にする 29 commentTableView.estimatedRowHeight = 66 30 commentTableView.rowHeight = UITableView.automaticDimension 31 } 32 33 // 設定 34 func numberOfSectionsInTableView(tableView: UITableView) -> Int { 35 return _items.count 36 } 37 38 // 設定(行数) 39 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 40 return _items[section].Items.count 41 } 42 43 //セクション数の設定 44 func numberOfSections(in tableView: UITableView) -> Int { 45 return _items.count 46 } 47 48 // 設定(セクションタイトル) 49 func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 50 return _items[section].SectionName 51 } 52 53 // 設定(セル) 54 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 55 let item = _items[indexPath.section].Items[indexPath.row] 56 57 let cell = tableView.dequeueReusableCell(withIdentifier: "DisneyCell", for: indexPath as IndexPath) 58 cell.textLabel?.numberOfLines=0 59 cell.textLabel?.text = item.Name 60 cell.imageView?.image = UIImage(named: item.Image) 61 62 //セルのサイズを指定 63 image.frame = CGRect(x: 0, y: 0, width: 50, height: 50) 64 return cell 65 } 66 67 //セルタップ時にセルの内容を取得する 68 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 69 let item = _items[indexPath.section].Items[indexPath.row] 70 71 print(item.Name) 72 } 73} 74 75

AssetCatalog
イメージ説明

info.Plist
イメージ説明

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

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

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

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

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

guest

回答1

0

ベストアンサー

UITableViewCell の AutoLayout の制約の付け方だと思います。

width, height を 50pt に設定して,上下の制約を 12pt にしてみたら下記です。
(数字は前後させてください)
ポイントは bottom の制約を >= 12 にすることです。
一行の場合は画像の方のマージンにしたいからです。
イメージ説明

ラベル側も考え方は同じで
上の制約をここでは画像の中央にするために 27pt 与えています。
こちらのポイントも bottom の制約を >= 12 にすることです。
イメージ説明

ラベルの方が複数行になる場合,ラベルの高さが増えても
画像の下の制約が 12pt 以上を満たすため問題ないです。

セルの自動計算は上下の制約が破綻していなければ聞いてくれます。
問題点③は書いておいた方がいいかなと思います。

self.tableView.estimatedRowHeight = 74 // 数字は適当でもいい self.tableView.rowHeight = UITableView.automaticDimension

サンプルコード書いたのでよかったら参考にしてください。

https://github.com/MilanistaDev/FlexibleCellSample

イメージ説明

投稿2020/08/30 17:20

TakuyaAso

総合スコア1361

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

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

Risney

2020/09/09 12:41

TakuyaAso様 ご回答ありがとうございます。 画像はサイズを指定することでサイズが爆発することはなくなりました! Plist内の文字を改行したところ、 3行以下の場合は問題なく表示されましたが、 3行以上にすると3点リーダで省略されてしまいます。 現状、ラベルはStoryBoardに配置していないのですが、 ViewController内でラベルの高さを可変にできるのでしょうか? (Labelを配置するとサブクラスを作成しないといけないので…)
TakuyaAso

2020/09/09 13:09 編集

AutoLayoutによる制約をコードで書けば可能だと思います。 セルのレイアウト想定図をみて どのアイテムとどのアイテムの制約かを確認しながら equalTo と greaterThanOrEqualTo を使ってセットすればわかりやすいかと思います。 参考 https://qiita.com/dddisk/items/8001598ea7951bcdcc30
Risney

2020/09/10 07:48 編集

気になって色々試していたら、ラベルも可変になっていることが判明しました。 画像を縦40×横40サイズだと2行になり、縦80×横80サイズにすると4文字表示される。 というようにラベル自体は可変になっておりました。 これもやはりAutoLayoutの制約で解決するのでしょうか? また、AutoLayoutの制約方法ですが、 Viewの場合は以下の方法で可能ですが、 今回のようなtextの場合はviewと同じ方法(以下のような制約方法)でできるのでしょうか… 色々試してみたのですが出来ずでした… let redView = UIView() redView.backgroundColor = UIColor.red redView.frame = view.frame redView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(redView) redView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true ---以下略---
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問