StackView 中的 WKWebView 未正确调整大小

问题描述

我有一个 TableView,在其中一个单元格中,我有一个 StackView,里面有一个 WKWebView。 我正在尝试动态地重新调整 WKWebView 的大小,当视图的高度需要大于之前的高度时,它可以正常工作,但是如果我需要降低高度,它不会调整。

这个cell里面的内容是通过viewmodel函数configure来刷新的:

class AboutTableViewCell: UITableViewCell {
    weak var delegate: AboutTableViewCellDelegate?


    let aboutStackView: UIStackView = {
        let sv = UIStackView()
        sv.axis = .vertical
        sv.distribution = .equalSpacing
        sv.translatesAutoresizingMaskIntoConstraints = false
        sv.spacing = 6
        return sv
    }()

    let descriptionLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.customrobotoBold18
        label.text = DESCRIPTION_LABEL_TEXT
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    let webview: WKWebView = {
        var webview = WKWebView()
        webview.isOpaque = true
        webview.translatesAutoresizingMaskIntoConstraints = false
        webview.scrollView.isScrollEnabled = false
        return webview
    }()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(style: UITableViewCell.CellStyle,reuseIdentifier: String?) {
        super.init(style: style,reuseIdentifier: reuseIdentifier)
        self.contentView.isUserInteractionEnabled = true
        newCommentTextView.delegate = self
        webview.navigationDelegate = self

        addSubviews()
        configure()
        setupAutoLayout()
    }

    private func addSubviews() {
        self.contentView.addSubview(aboutStackView)
        aboutStackView.addArrangedSubview(descriptionLabel)
        webViewHeightConstraint = webview.heightAnchor.constraint(equalToConstant: 1.0)
        webViewHeightConstraint?.isActive = true
        aboutStackView.addArrangedSubview(webview)
    }

    private func setupAutoLayout() {
        NSLayoutConstraint.activate([
            aboutStackView.topAnchor.constraint(equalTo: contentView.topAnchor,constant: 10),aboutStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor,aboutStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor,constant: -10),aboutStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor,constant: -10)
        ])
    }

    private func configure() {
        self.contentView.clipsToBounds = true
        guard let session = RefreshToken.shared.session else {
            return
        }
        self.contentView.backgroundColor = .mainBackgroundColor
    }
}

这里是用于在 loadHTMLString 被触发后执行高度变化的扩展:

extension AboutTableViewCell: WKNavigationDelegate {
    func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!) {
        webView.evaluateJavaScript("document.readyState",completionHandler: { result,error in

            if result == nil || error != nil {
                return
            }

            webView.evaluateJavaScript("document.body.offsetHeight",error in
                if let height = result as? CGFloat {
                    self.webViewHeightConstraint?.constant = height
                }
            })
        })
    }
}

这是用于填充内容的视图模型:

class Aboutviewmodel {

   private var rawHTML: String?

   init(html: String) {
       rawHTML = html
   }

    func configure(with cell: AboutTableViewCell) {
        self.cell = cell

        if let raw = self.rawHTML {
            let headerString = "<head><Meta name='viewport' content='width=device-width,initial-scale=0.7,maximum-scale=0.7,minimum-scale=0.7,user-scalable=no'/><link rel=\"preconnect\" href=\"https://fonts.gstatic.com\"><link href=\"https://fonts.googleapis.com/css2?family=Roboto&display=swap\" rel=\"stylesheet\"><style>a:link {color: #ffc000;text-decoration: none;}body{font-family: 'Roboto',sans-serif;}</style>"
        
            let finalHTML = raw.replacingOccurrences(of: "/data/",with: "https://" + NetworkService.HostName + "/data/").replacingOccurrences(of: "<pre>",with: "<small style='word-wrap:break-word;color:rgba(0,0.4);'>").replacingOccurrences(of: "</pre>",with: "</small>")
        
            cell.webview.loadHTMLString(headerString + finalHTML,baseURL: nil)
        }
    }
}

关于为什么我的内容内容需要时没有缩小的任何想法? 正如我提到的,它在需要扩展高度时确实有效。

解决方法

尝试在 evaluateJavaScript 回调中移动您的子视图初始化:

class AboutTableViewCell: UITableViewCell {

    ...

    override init(style: UITableViewCell.CellStyle,reuseIdentifier: String?) {
        super.init(style: style,reuseIdentifier: reuseIdentifier)
        self.contentView.isUserInteractionEnabled = true
        newCommentTextView.delegate = self
        webview.navigationDelegate = self

        configure()
        setupAutoLayout()
    }

    private func addSubviews(_ height: CGFloat = 1.0) {
        self.contentView.addSubview(aboutStackView)
        aboutStackView.addArrangedSubview(descriptionLabel)
        webview.heightAnchor.constraint(equalToConstant: height).isActive = true
        aboutStackView.addArrangedSubview(webview)
        aboutStackView.layoutIfNeeded()
    }

    ...
}

extension AboutTableViewCell: WKNavigationDelegate {
    func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!) {
        webView.evaluateJavaScript("document.readyState",completionHandler: { result,error in

            if result == nil || error != nil {
                addSubviews()
                return
            }

            webView.evaluateJavaScript("document.body.offsetHeight",error in
                guard let height = result as? CGFloat else { 
                    addSubviews()
                    return 
                }
                    
                addSubviews(height)
            })
        })
    }
}