0

I have a tableview cell with a layout like this -

ContentView 
   - StackView
       - Fixed Height UILabel
       - UIView (Webview Container)
       - Fixed Height UILabel
       - ... more views

Now I am trying to add a webview inside this UIView like this -

func prepareQuestionWebView() {
        let webConfiguration = WKWebViewConfiguration()
        let contentController = WKUserContentController();
        webConfiguration.userContentController = contentController
        webView = WKWebView(frame: CGRect(origin: CGPoint.zero, size: questionView.frame.size))
        webView?.scrollView.isScrollEnabled = false
        webView?.scrollView.bounces = false
        webView?.scrollView.bouncesZoom = false
        webView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        webView?.translatesAutoresizingMaskIntoConstraints = false
        webView?.tag = -1
        webView?.navigationDelegate = self
        questionView.removeAllSubviews()
        questionView.addSubview(webView!)
        webView?.contentScaleFactor = 1
    }

I have created the following outlets for my stack view and webview container -

@IBOutlet weak var questionView: UIView!
@IBOutlet weak var rootStack: UIStackView!

and to make the questionView frame size as equal to the webview's content size I am doing this -

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        if webView.isLoading == false {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { 
               webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (result, error) in
                    if let height = result as? CGFloat {
                        self.setHeightData(height, webView)
                    }
                })
            }
        }
    }

    func setHeightData(_ height: CGFloat, _ wv: WKWebView) {
        switch wv.tag {
            case -1:
                questionView.frame = CGRect.init(x: 0, y: 36, width: rootStack.frame.width, height: height)
            default:
                break
        }
        wv.layoutSubviews()
        questionView.layoutIfNeeded()
        rootStack.layoutSubviews()
        rootStack.layoutIfNeeded()
    }

This updates the webview size and its container's size but for some reason the elements after the webview container in the stackview are not updated and hence they overlap with the webview container

So, how can I update the stackview view after I set the questionView's height equal to its webview's contents ?

Or is there another way to make the questionView (webview container) height dynamic according to its content and make the rest of the views move down when its height changes ?

Harshit Laddha
  • 2,044
  • 8
  • 34
  • 64

1 Answers1

1

You have set the stackview and other view's size using autolayout and you are setting webview and container view's size using frames. Because of this, stackview and other views inside it are unable to adjust. Rather than giving webview's container a frame, constraint its four walls to webview's four walls and give the webview a height constraint.

Jayant Jaiswal
  • 171
  • 1
  • 8
  • Thanks, it works for me now. One more question I have this stackview inside a tableview cell but since the tableview rows needs explicit height I have just given it a large enough number (1000) to it for now but now can I also set the table view's cell size to be just equal to the height of this stackview ? – Harshit Laddha Apr 07 '19 at 06:07
  • you can override the intrinsic content size of the tableview cell to include the height of the stack view. – Jayant Jaiswal Apr 07 '19 at 06:13
  • okay, so I saw this post https://stackoverflow.com/questions/39626182/can-you-get-a-uitableviews-intrinsic-content-size-to-update-based-on-the-number for overriding invalidateIntrinsicContentSize() method and this method is available inside my cell. But, I can't find any function definition to override for intrinsicContentSize in both my table view controller and table view cell. How can I override this content size from inside the cell after this height update ? – Harshit Laddha Apr 07 '19 at 06:25
  • its not a function, its a property of uiview. Override it in the tableviewcell – Jayant Jaiswal Apr 07 '19 at 06:29
  • Okay, so I did this - override var intrinsicContentSize: CGSize { get { return CGSize(width: self.contentView.width, height: self.contentView.height) } set { invalidateIntrinsicContentSize() } } and then tried to set this property like - intrinsicContentSize = CGSize.init(width: rootStack.frame.width, height: rootStack.frame.height) self.invalidateIntrinsicContentSize() but the cell's size doesn't change – Harshit Laddha Apr 07 '19 at 06:42
  • do domething like override var intrinsicContentSize: CGSize { var size = super.intrinsicContentSize size.height = return size } – Jayant Jaiswal Apr 07 '19 at 06:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/191386/discussion-between-deadman-and-jayant-jaiswal). – Harshit Laddha Apr 07 '19 at 07:01