I've been struggling with this for two days, so I come hat in hand to the wise people of the internet.
I am showing an article as part of my UITableView
. For this to display correctly, I need to give the delegate a height for the cell, which I want to be the same as the UIWebView
's height, so I can disable scroll on the WebView and display the web content in its entirety as a static cell.
My first approach was to render it in the heightForRowAtIndexpath
method, but this did obviously not work as I need the wait for the UIWebViewDelegate
to tell me when the web view is fully loaded and has a height. After a while I found a working solution, which used the web view delegate to refresh the cell height when the web view was loaded.
The works fine until the screen size changes. Either from rotate or from full-screening my UISplitView
. I forced an update on it in the didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation)
, but this causes it to flash about 10 times before settling into the correct height. I logged this change, and it seems the WebView is calling itself multiple times, causing a loop.
As seen in this log, starting from when I rotated the screen.
It flashes once every time it reloads, and as you can see, it reloads itself a bunch of times.
So. I need a way to show an entire web views content inside a uitableview, and reliably get the height when the screen size changes. If anyone has managed this in any way before, please tell me. I will give a bounty and my firstborn child to anyone who can resolve this, as it's driving me insane.
Here's my relevant code.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch indexPath.row {
case 4:
//Content
print("Height for row called")
return CGFloat(webViewHeight)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch (indexPath.row){
//HTML Content View
case 4:
let cell = tableView.dequeueReusableCellWithIdentifier("ContentCell", forIndexPath: indexPath)
var contentCell = cell as? ContentCell
if contentCell == nil {
contentCell = ContentCell()
}
contentCell?.contentWebView.delegate = self
contentCell?.contentWebView.scrollView.userInteractionEnabled = false
contentCell?.contentWebView.loadHTMLString((post?.contentHTML)!, baseURL: nil)
print("Cell For row at indexpath called")
return contentCell!
}
func webViewDidFinishLoad(webView: UIWebView) {
updateHeight()
}
func updateHeight(){
let webView = (self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: 4, inSection: 0)) as! ContentCell).contentWebView
if self.webViewHeight != Double(webView.scrollView.contentSize.height) {
print("Previous WV Height = \(self.webViewHeight), New WV Height = \(webView.scrollView.contentSize.height)")
self.webViewHeight = Double(webView.scrollView.contentSize.height)
tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 4, inSection: 0)], withRowAnimation: .Automatic)
} else {
return
}
}
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
print("rotated")
self.updateHeight()
//tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 4, inSection: 0)], withRowAnimation: .Automatic)
}
I solved this by changing the .Automatic to .None in the row change animation. Its still a bad solution, but at least it doesn't flicker anymore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With