##初めに
xibで作ったTableViewCellを想定しています
xibでのセルの作り方はこちらを参照ください
https://qiita.com/Secret-Base36/items/2a9a3989479559ba36ba
##環境
Xcode 12.2
##1. TextViewの設定
- Scrolling Enableのチェックを外す
##2. TableViewのセルの高さの設定
TableViewのheightForRowAtメソッドで可変に設定
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//セルの推定最低高さ(不要?)
secondTableView.estimatedRowHeight = 50
//セルの高さを可変に設定
return UITableView.automaticDimension
}
estimatedRowHeight(セルの推定高さ)は記述しなくても結果は変わらなかった
文字量によってセルの高さが変わる様になった!
###微調整
上の図の様に最小高さの場合に、他のUIが重なるなど影響が出る場合は、制約で調整すると良い
####ここまでで高さを動的に変更させるまでは終わり
ここからは、幅も動的に変更させる方法
##3.textからViewの幅を計算する
TableViewCellのクラスにメソッドを追加する
//セルのTextViewの幅の計算
private func estimateFrameForTextView(text: String) -> CGRect{
//最大値
let size = CGSize(width: 200, height: 1000)
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
return NSString(string: text).boundingRect(with: size, options: options, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14)], context: nil)
//systemFont(ofSize)にはTextViewに設定したサイズを設定する
}
##4.Textを受ける変数を定義して、幅の制約をCellのクラスとOutlet接続
接続名は"textViewWidthConstraint"としました
##5.作成したCell側の変数にTextを渡す
TableViewのcellForRowAtからCellのmsgText変数にテキストを格納
//セルの内容
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = secondTableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! SecondTableViewCell
cell.backgroundColor = .lightText
//cell.textView.text = textArray[indexPath.row]
//★★★ Cellクラスの変数に格納 (ここで渡している)
cell.msgText = textArray[indexPath.row]
return cell
##6.Cellクラス側で幅を計算させて、TextViewの幅を変更するコードを書く
受け取ったテキストをもとに、estimateFrameForTextViewメソッドで幅を計算させて、その幅でTextViewの幅を変更する
//ViewControllerからテキストを受け取る変数
var msgText :String? {
//didSetで値の変更後(計算後)に通知
didSet {
//nilチェック
guard let text = msgText else { return }
//幅計算メソッドで幅を計算する + 10は幅に余裕を持たせる為(無いと不用意な改行が入ることも)
let width = estimateFrameForTextView(text: text).width + 10
textViewWidthConstraint.constant = width
textView.text = text
}
}
####以上です
##最後に
情報が間違っているなどありましたら、お手数ですがご指摘いただけると幸いです。
下に全コードを載せておきます
import UIKit
class SecondTableViewCell :UITableViewCell{
//ViewControllerからテキストを受け取る変数
var msgText :String? {
//didSetで値の変更後(計算後)に通知
didSet {
//nilチェック
guard let text = msgText else { return }
//幅計算メソッドで幅を計算する + 10は幅に余裕を持たせる為(無いと不用意な改行が入ることも)
let width = estimateFrameForTextView(text: text).width + 10
textViewWidthConstraint.constant = width
textView.text = text
}
}
//★★★UIとの接続
@IBOutlet weak var cellImageView: UIImageView!
@IBOutlet weak var textView: UITextView!
@IBOutlet weak var textViewWidthConstraint: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
//CellのUIのプロパティー変更
cellImageView.layer.cornerRadius = 25
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
//セルのTextViewの幅の計算
private func estimateFrameForTextView(text: String) -> CGRect{
//最大値
let size = CGSize(width: 200, height: 1000)
let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
return NSString(string: text).boundingRect(with: size, options: options, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20)], context: nil)
//systemFont(ofSize)にはTextViewに設定したサイズを設定する
}
}
import UIKit
class SecondViewController : UIViewController{
private let cellId = "cellId"
var textArray = ["あいうえお",
"あいうえお\nかきくけこ",
"あいうえおかきくけこさしすせそ",
"あいう\nえおかきくけこさしすせそ\nたちつてと"]
@IBOutlet weak var secondTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
secondTableView.delegate = self
secondTableView.dataSource = self
//セルの登録(Xibファイル名:SecondViewTableViewCell.xibの場合)
secondTableView.register(UINib(nibName: "SecondViewTableViewCell", bundle: nil), forCellReuseIdentifier: cellId)
}
}
extension SecondViewController :UITableViewDelegate,UITableViewDataSource{
//セルの高さ
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//Cellの高さを可変にする
return UITableView.automaticDimension
}
//セルの個数
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return textArray.count
}
//セルの内容
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = secondTableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! SecondTableViewCell
cell.backgroundColor = .lightText
//cell.textView.text = textArray[indexPath.row]
//Cellクラスの変数に格納
cell.msgText = textArray[indexPath.row]
return cell
}
}