在我的iOS应用中,我要显示包含HTML的多个项目。为此,我构建了一个 NewsListViewController ,其中包含一个 UITableView 。对于该 UITableView (导出:newsListTableView),我创建了一个名为 NewsTableViewCell 的自定义 UITableViewCell ,它将通过委托(delegate)加载到该表中。 NewsTableViewCell 拥有一个 WKWebKit 控件,该控件将显示我的HTML。这是我的代码:
NewsListViewController.swift
import UIKit
class NewsListViewController: UIViewController {
@IBOutlet weak var newsListTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.newsListTableView.delegate = self
self.newsListTableView.dataSource = self
self.newsListTableView.register(UINib(nibName: "NewsTableViewCell", bundle: nil), forCellReuseIdentifier: "cell")
}
}
extension NewsListViewController: UITableViewDelegate {
}
extension NewsListViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 300.0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! NewsTableViewCell
cell.titleText = "My Title"
cell.dateTimeText = "01.01.1998"
cell.contentHtml = "<html><head><meta name=\"viewport\" content=\"initial-scale=1.0\" /><style>html, body { margin: 0; padding: 0; font-size: 15px; }</style></head><body><b>Hello News</b><br />Hello News<br />Hello News<br />Hello News</body></html>"
return cell
}
}
NewsTableViewCell.xib
我的 WKWebKit (导出:newsContentPreviewWebView)位于 UIView (导出:newsContentViewContainer)内部,具有适当的约束条件,可以随 UIView 一起增长。我的 UIView 也带有适当的约束,可以随整个单元一起增长。
NewsTableViewCell.swift
import UIKit
import WebKit
@IBDesignable class NewsTableViewCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var dateTimeLabel: UILabel!
@IBOutlet weak var newsContentViewContainer: UIView!
@IBOutlet weak var newsContentPreviewWebView: WKWebView!
@IBInspectable var titleText: String? {
get {
return self.titleLabel.text
}
set(value) {
self.titleLabel.text = value
}
}
@IBInspectable var dateTimeText: String? {
get {
return self.dateTimeLabel.text
}
set(value) {
self.dateTimeLabel.text = value
}
}
@IBInspectable var contentHtml: String? {
get {
return nil
}
set(value) {
self.newsContentPreviewWebView.loadHTMLString(value ?? "", baseURL: nil)
}
}
override func awakeFromNib() {
super.awakeFromNib()
self.newsContentPreviewWebView.navigationDelegate = self
}
}
extension NewsTableViewCell: WKNavigationDelegate {
}
结果如下:
现在,我希望单元格尽可能小,但仍要显示完整的 WKWebKit 内容。
当我删除...
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 300.0
}
...从 NewsListViewController.swift 中开始,单元格高度将仅遵循 WKWebKit 控件上方的标签:
我认为这正在发生,因为当应用程序调整单元格大小时,我的 WKWebKit 的内容未加载。
我试着通过解决 WKWebKit 的>>来完成此问题,以解决此问题,在我的 NewsTableViewCell.swift 中完成导航<
extension NewsTableViewCell: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
let h: CGFloat = height as! CGFloat
let newsContentFrame: CGRect = self.newsContentViewContainer.frame
self.newsContentViewContainer.frame = CGRect(x: newsContentFrame.minX, y: newsContentFrame.minY, width: newsContentFrame.width, height: h)
let tableCellFrame: CGRect = self.frame
self.frame = CGRect(x: tableCellFrame.minX, y: tableCellFrame.minY, width: tableCellFrame.width, height: tableCellFrame.height + h)
})
}
})
}
}
结果如下:
单元格重叠,这表示我正在尝试以错误的方式解决此问题。
自动调整自定义表单元格的大小以适合其所有内容(包括 WKWebKit 的内容)的正确方法是什么?
最佳答案
问题是您永远不会给自己的细胞一个高度。手动设置框架
不好。您应该始终使用专用的委托(delegate)方法或估计的行高技术(Using Auto Layout in UITableView for dynamic cell layouts & variable row heights)。
问题很棘手:您需要等待webview加载以计算其高度。但是调用heightForCell
时需要它的高度,以便在加载Webview的内容之前。
我看到5个解决方案:
completionHandler
时,您将调用一个委托(delegate)(例如,您的viewcontroller),该委托(delegate)将重新加载相应的单元格,并为其提供刚刚计算出的正确高度。这个解决方案很简单,但是在每次加载之前,您都需要在单元格上设置错误的高度。因此,您可以在单元格中定义加载状态,但是当单元格即将出现时,您总是会有一点小故障。 Operation
,它将等待单元格的html加载并评估给定的javascript。完成所有操作后,重新加载表格 View 关于ios - 如何使用基础WKWebKit自动调整UITableViewCell的大小,使其尊重Web View 的内容?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48463531/