webkitview tutorial new ios xcode swift uitableview uiwebview

ios - tutorial - UITableViewCell con altura dinámica UIWebView



webkitview swift 4 (9)

Después de calcular la altura de webview Use DispatchQueue para volver a cargar la altura de TableViewcell DispatchQueue.main.async . Evita los espacios vacíos anormales y se bloquea al volver a cargar el marco de webview

func webViewDidFinishLoad(_ webView: UIWebView) { var frame : CGRect = webVwModule.frame; frame.size.height = 1; self.webVwModule.frame.size = webVwModule.sizeThatFits(.zero) frame.size = self.webVwModule.frame.size; webView.frame = frame; webViewContentHeight = self.webVwModule.frame.size.height; isWebViewLoaded = true DispatchQueue.main.async(execute: { () -> Void in self.tableView.beginUpdates() self.tableView.endUpdates() }) } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return webViewContentHeight! }

Tengo una vista de tabla con celdas que tienen una vista web en ellas, quiero que la altura de la celda coincida con la altura de la vista web.

Este es el código que uso:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("newsCell") as! NewsTableViewCell cell.webView.loadHTMLString("test<br>test<br>test<br>test<br>test<br>test", baseURL: nil) cell.webView.delegate = self var webFrame = cell.webView.frame var cellFrame = cell.frame cell.frame = CGRectMake(cellFrame.origin.x, cellFrame.origin.y, cellFrame.width, webFrame.height + 20) cell.backgroundColor = UIColor.redColor() return cell } func webViewDidFinishLoad(webView: UIWebView) { println("finished loading") var frame = webView.frame frame.size.height = 1 webView.frame = frame var fittingSize = webView.sizeThatFits(CGSizeZero) frame.size = fittingSize webView.frame = frame var height: CGFloat = frame.height println(height) webView.frame = CGRectMake(frame.origin.x, frame.origin.x, frame.size.width, frame.size.height) newsTable.beginUpdates() newsTable.endUpdates() }

Y este es el resultado: https://postimg.cc/image/8qew1lqjj/

La vista web es la altura correcta, pero la celda no lo es. ¿Cómo puedo solucionar este problema?


Es un trabajo para mí, una forma fácil de cargar cadenas HTML en WebView con dinámica.

Primero tome textView en TableViewCell con deshabilitación de desplazamiento y luego tome WebView, aplique la restricción de cero en los 4 lados con ContentView. Ahora asigne la misma restricción de altura a ambos, vista de texto y WebView. Ahora, dé el mismo texto a ambas vistas como se muestra a continuación.

Para la interfaz de usuario limpia Ocultar textoVer desde XIB o storyBoard.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return 100 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "tableviewcell") as! tableviewcell let theString : String = "</p><img src=''https://pbs.twimg.com/profile_images/655066410087940096/QSUlrrlm.png'' width=100 height=100 /><h2>Subheader</h2>" let theAttributedString = try! NSAttributedString(data: theString.data(using: String.Encoding.utf8, allowLossyConversion: false)!,options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) cell.textview.attributedText = theAttributedString cell.webview.loadHTMLString(theString, baseURL: nil) return cell }


Implemente el delegado de UITableview altura para la ruta de acceso para devolver la altura del marco de vista web.


La forma más fácil y elegante es

  1. Añadir restricción de diseño de altura para webview
  2. Agregue Webview El delegado terminó de cargar y luego establezca contentSize height en una constante de restricción de diseño de altura.

  3. Mantenga una instancia de tableview o haga un delegado - bloque - cierre a tableview principal.

  4. Llame a tableview beginupdate endupdate para informar a tableview que deben validar el diseño.

class WebViewTableViewCell: UITableViewCell { weak var viewController: ViewController? = nil @IBOutlet weak var webView: UIWebView! @IBOutlet weak var heightLayoutConstraint: NSLayoutConstraint! override func awakeFromNib() { super.awakeFromNib() webView.loadRequest(URLRequest(url: URL(string: "https://tinhte.vn")!)) webView.delegate = self webView.scrollView.isScrollEnabled = false // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } } extension WebViewTableViewCell: UIWebViewDelegate { func webViewDidFinishLoad(_ webView: UIWebView) { heightLayoutConstraint.constant = webView.scrollView.contentSize.height viewController?.tableView.beginUpdates() viewController?.tableView.endUpdates() } }


La mejor manera funcionó para mí.

var heightOfWebview: CGFloat = 0 func webViewDidFinishLoad(_ aWebView: UIWebView) { var frame: CGRect = aWebView.frame frame.size.height = 1 aWebView.frame = frame let fittingSize = aWebView.sizeThatFits(CGSize.zero) frame.size = fittingSize aWebView.frame = frame heightOfWebview = Int(fittingSize.height) tableView.beginUpdates() tableView.endUpdates() print("Calling webViewDidFinishLoad. Cell size value: /(heightOfWebview)") } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return heightOfWebview }


TableView cambiará el tamaño de las celdas, solo necesita implementar tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat delegate method.

Sí, inicialmente no sabes la altura de WebView, pero puedes calcularlo y luego pedir a TableView que vuelva a cargar la celda. Algo como esto:

class TableViewController: UITableViewController, UIWebViewDelegate { var content : [String] = ["test1<br>test1<br>test1<br>test1<br>test1<br>test1", "test22<br>test22<br>test22<br>test22<br>test22<br>test22"] var contentHeights : [CGFloat] = [0.0, 0.0] // ... override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("newsCell", forIndexPath: indexPath) as! NewsTableViewCell let htmlString = content[indexPath.row] let htmlHeight = contentHeights[indexPath.row] cell.webView.tag = indexPath.row cell.webView.delegate = self cell.webView.loadHTMLString(htmlString, baseURL: nil) cell.webView.frame = CGRectMake(0, 0, cell.frame.size.width, htmlHeight) return cell } override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return contentHeights[indexPath.row] } func webViewDidFinishLoad(webView: UIWebView) { if (contentHeights[webView.tag] != 0.0) { // we already know height, no need to reload cell return } contentHeights[webView.tag] = webView.scrollView.contentSize.height tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: webView.tag, inSection: 0)], withRowAnimation: .Automatic) } // ... }


Tengo una solución más que deberías considerar. Haga una restricción de altura y UITableViewCell a su clase UITableViewCell . Luego implemente la func webViewDidFinishLoad(_ webView: UIWebView) método delegado func webViewDidFinishLoad(_ webView: UIWebView) , y cuando se le llame, establezca la restricción de altura para que sea igual a webView.scrollView.contentSize.height .


Swift 4

Respuesta de ifau modificada para Swift 4, utilizando UITableView lugar de UITableViewController .

En el guión gráfico, tome un UITableView . Añadir 1 célula prototipo a ella. Mantenga el reuseIdentifier de la celda en " cell ". Arrastre un webView a la celda y establezca las restricciones webView , finales, superiores e inferiores a 0. Establezca la clase de celda en TableViewCell

TableViewCell.swift

Conecte la salida webView al guión gráfico:

import UIKit class TableViewCell: UITableViewCell { @IBOutlet weak var webView: UIWebView! override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } }

ViewController.swift

Conecte la salida tableView al guión gráfico:

import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIWebViewDelegate { @IBOutlet weak var tableView: UITableView! var content : [String] = ["test1<br>test1<br>test1", "test22<br>test22<br>test22<br>test22<br>test22<br>test22"] var contentHeights : [CGFloat] = [0.0, 0.0] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. tableView.dataSource = self tableView.delegate = self } public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return content.count } public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ let cell : TableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell let htmlString = content[indexPath.row] let htmlHeight = contentHeights[indexPath.row] cell.webView.tag = indexPath.row cell.webView.delegate = self cell.webView.loadHTMLString(htmlString, baseURL: nil) cell.webView.frame = CGRect(x: 0, y: 0, width: cell.frame.size.width, height: htmlHeight) return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if contentHeights[indexPath.row] != 0 { return contentHeights[indexPath.row] } } public func webViewDidFinishLoad(_ webView: UIWebView){ if (contentHeights[webView.tag] != 0.0) { // we already know height, no need to reload cell return } contentHeights[webView.tag] = webView.scrollView.contentSize.height tableView.reloadRows(at: [IndexPath(row: webView.tag, section: 0)], with: .automatic) } }


var heightOfWebview=0 func webViewDidFinishLoad(_ aWebView: UIWebView) { var frame: CGRect = aWebView.frame frame.size.height = 1 aWebView.frame = frame let fittingSize = aWebView.sizeThatFits(CGSize.zero) frame.size = fittingSize aWebView.frame = frame heightOfWebview = Int(fittingSize.height) tableView.beginUpdates() tableView.endUpdates() print("Calling webViewDidFinishLoad. Cell size value: /(heightOfWebview)") } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return CGFloat(220+heightOfWebview) /// 220 is my static value }