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

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

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

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

Q&A

解決済

1回答

1664閲覧

カスタムテーブルビューセルの高さを WKWebView のコンテンツの高さに応じて決めたい。

ringotubame

総合スコア21

Swift

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

0グッド

0クリップ

投稿2022/01/19 18:19

カスタムテーブルビューセルの高さをこのセルに埋めた WKWebView のコンテンツの高さに応じて決めたい。

テーブルビューを設置した ViewController は下記のような感じ

セル1
セル2
webCell

tableView は四方に 0 0 0 0 の autolayout による制約付き。

html 読み込み後に、
webCell.webViewHeightConstraint?.constant = height as! CGFloat
として高さを更新しているつもりなのになぜか webCell の高さがかわらない。
高さは初期値の 400 のまま

現状
イメージ説明

// エラーメッセージ
[LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x60000129f1b0 WKWebView:0x13c021800.height == 656 (active)>",
"<NSLayoutConstraint:0x600001284190 V:[WKWebView:0x13c021800]-(0)-| (active, names: '|':UITableViewCellContentView:0x13ad83730 )>",
"<NSLayoutConstraint:0x600001284a00 V:|-(0)-[WKWebView:0x13c021800] (active, names: '|':UITableViewCellContentView:0x13ad83730 )>",
"<NSLayoutConstraint:0x60000129ec10 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x13ad83730.height == 400.5 (active)>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x60000129f1b0 WKWebView:0x13c021800.height == 656 (active)>

自動で高さが更新されないので webView:didFinish navigation:メソッド内でテーブルビューセルを reload すると無限ループでこまってます。
セルの高さを webView の高さ 656 にしたいのに勝手に break されて 400 になってる。
400 は .xib で設定した初期値。これが更新したつもりが更新できてない。

swift

1// テーブルビューを設置した ViewController側 2func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 3 var cell = tableView.dequeueReusableCell(withIdentifier: "myCell1", for: indexPath) 4 5 switch indexPath.row { 6 case 2: 7 print("webCell") 8 let webCell = tableView.dequeueReusableCell(withIdentifier: "webCell", for: indexPath) as! MYWebTableViewCell 9 10 webCell.myWebView.navigationDelegate = self 11 webCell.loadHTMLContent(htmlContent: htmlStr) 12 return webCell 13 14 default: 15 print("case default: ") 16 cell = tableView.dequeueReusableCell(withIdentifier: "myCell1", for: indexPath) 17 } 18 19 return cell 20} 21 22func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 23 webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { [self] (height, error) in 24 let webCell = myTableView.cellForRow(at: IndexPath(row: 2, section: 0)) as! MYWebTableViewCell 25 webCell.webViewHeightConstraint?.constant = height as! CGFloat 26 27 print(webCell.webViewHeightConstraint?.constant) // Optional(656.0) 28 print("webView.frame : ", webView.frame) // (0.0, 0.0, 320.0, 400.5) 29 30 // myTableView.reloadRows(at: [IndexPath(row: 2, section: 0)], with: .none) 31 // webCell.layoutIfNeeded() 32 // self.superview?.layoutIfNeeded() 33 }) 34 } 35

swift

1class MYWebTableViewCell: UITableViewCell{ 2 @IBOutlet weak var myWebView: WKWebView! 3 @IBOutlet weak var webViewHeightConstraint: NSLayoutConstraint! 4 5 override func awakeFromNib() { 6 super.awakeFromNib() 7 print("webViewHeightConstraint : ", webViewHeightConstraint) 8 9 myWebView.scrollView.isScrollEnabled = false 10 }

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

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

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

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

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

guest

回答1

0

自己解決

自己解決しました。

・ performBatchUpdates(_:completion:)
Animates multiple insert, delete, reload, and move operations as a group.

https://developer.apple.com/documentation/uikit/uitableview/2887515-performbatchupdates

高さの更新処理を myTableView.reloadRows から myTableView.performBatchUpdates(nil, completion: nil) に変更
高さの更新のみなら、引数のクロージャは nil でいい。

webview 読み込み完了 → table を reload → webview 読み込み完了 → table を reload → webview 読み込み完了

この無限ループは起こしちゃだめなので、html を読み込み後リロードすることなく高さ更新できるperformBatchUpdates(_:completion:) を使う。

解決版では WKWebView をコンテナview にのせてからセルに追加してるが、このコンテナはなくてもよいはず。

swift

1func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 2 3 webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { [self] (height, error) in 4 print("height : ", height ?? 0) 5 6 let webCell = myTableView.cellForRow(at: IndexPath(row: 2, section: 0)) as! MYWebCell2 7 webCell.contenaHeightConstraint.constant = height as! CGFloat 8 9 myTableView.performBatchUpdates(nil, completion: nil) 10 }) // END evaluateJavaScript 11 }

投稿2022/01/21 11:42

ringotubame

総合スコア21

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問