Размер динамического содержимого UIWebView

Я оглядывался и не мог видеть быстрых способов сделать это. Я пытаюсь повысить динамическую высоту моего UIWebViews. У меня есть UIWebView, который загружает данные с помощью функции loadHtmlString. Дело в том, что я загружаю данные из базы данных sqlite, каждый раз, когда я загружаю другую строку различной длины, и, естественно, веб-представление получает разную высоту. Теперь мне нужно знать, как сделать UIWebView точной высотой, чтобы загрузить мой следующий контент прямо под webView. Это то, что я до сих пор

var jobSkillView = UIWebView(frame: CGRectMake(-5, 480.0, screenWidth, 300.0))
jobSkillView.loadHTMLString("<html><body p style='font-family:arial;font-size:16px;'>" + jobSkills + "</body></html>", baseURL: nil)
jobSkillView.stringByEvaluatingJavaScriptFromString("document.body.innerHTML")
jobSkillView.scrollView.scrollEnabled = true
jobSkillView.scrollView.bounces = true
jobSkillView.sizeToFit()
border.addSubview(jobSkillView)

Я нашел что-то подобное на SO, но не уверен, как связать его с фреймом UIWebView:

func webViewDidFinishLoad(jobSkillView : UIWebView){
    // Change the height dynamically of the UIWebView to match the html content
    var jobSkillViewFrame: CGRect = jobSkillView.frame
    jobSkillViewFrame.size.height = 1
    jobSkillView.frame = jobSkillViewFrame
    var fittingSize: CGSize = (jobSkillView.sizeThatFits(CGSizeZero))
    jobSkillViewFrame.size = fittingSize
    // webViewFrame.size.width = 276; Making sure that the webView doesn't get wider than 276 px
    jobSkillView.frame = jobSkillViewFrame
    var jobSkillViewHeight = jobSkillView.frame.size.height
}

Ответ 1

Этот пост был обновлен для Swift 5 & WKWebView


Так что это действительно отличная функция, которую вы там написали, OP!
Вот только более короткая и элегантная версия вашего кода:

// make sure to declare the delegate when creating your webView (add UIWebViewDelegate to class declaration as well)
myWebView.delegate = self

func webViewDidFinishLoad(webView: UIWebView) {
     webView.frame.size.height = 1
     webView.frame.size = webView.sizeThatFits(CGSize.zero)
}

Миграция в WKWebView

1) импортировать WebKit
2) сделать ваш ViewController наследовать от WKNavigationDelegate
3) подключить к WKWebView делегата: webView.navigationDelegate = self
4) реализовать следующую функцию протокола:

webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)

После миграции из UIWebView в WKWebView описанный выше подход, похоже, больше не работает.
Вместо этого вы можете изменить строку с помощью webView.sizeThatFits(CGSize.zero) на:

webView.frame.size = webView.scrollView.contentSize

Полный код для WKWebView будет:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.frame.size.height = 1
    webView.frame.size = webView.scrollView.contentSize
}

Ответ 2

это работало только для меня

func webViewDidFinishLoad(_ webView: UIWebView) {
    webView.frame.size.height = 1
    webView.frame.size = webView.sizeThatFits(.zero)
    webView.scrollView.isScrollEnabled=false;
    myWebViewHeightConstraint.constant = webView.scrollView.contentSize.height
    webView.scalesPageToFit = true
}

убедитесь, что вы создали выход для myWebViewHeightConstraint

Ответ 3

Вот мой пользовательский класс для работы с пользовательскими интерфейсами UIWebViews, в нем есть все, чтобы получить правильную высоту содержимого прокрутки, установить высоту UIWebView и создать настраиваемое ограничение по высоте, чтобы заставить работать автозапуск. Он также загружает пользовательский стиль CSS...

class CustomUIWebView: UIWebView, UIWebViewDelegate {

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.scrollView.scrollEnabled = false
        self.scrollView.bounces = false
        self.delegate = self
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.scrollView.scrollEnabled = false
        self.scrollView.bounces = false
        self.delegate = self
    }

    override func loadHTMLString(string: String!, baseURL: NSURL!) {
        var cssURL:String = NSBundle.mainBundle().pathForResource("webview", ofType: "css")!
        var s:String = "<html><head><title></title><meta name=\"viewport\" content=\"initial-scale=1, user-scalable=no, width=device-width\" /><link rel=\"stylesheet\" href=\"./webview.css\" ></link></head><body>"+string+"</body></html>";
        var url:NSURL

        if baseURL == nil {
            url = NSBundle.mainBundle().bundleURL
        } else {
            url = baseURL
        }

        super.loadHTMLString(s, baseURL: url)
    }

    func webViewDidFinishLoad(webView: UIWebView) {
        self.webViewResizeToContent(webView)
    }

    func webViewResizeToContent(webView: UIWebView) {
        webView.layoutSubviews()

        // Set to smallest rect value
        var frame:CGRect = webView.frame
        frame.size.height = 1.0
        webView.frame = frame

        var height:CGFloat = webView.scrollView.contentSize.height
        println("UIWebView.height: \(height)")

        webView.setHeight(height: height)
        let heightConstraint = NSLayoutConstraint(item: webView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.Height, multiplier: 1.0, constant: height)
        webView.addConstraint(heightConstraint)

        // Set layout flag
        webView.window?.setNeedsUpdateConstraints()
        webView.window?.setNeedsLayout()
    }

}

Ответ 4

У меня была проблема с:

let height = webView.scrollView.contentSize.height

Иногда моя высота веб-представления просто не вычислялась и оставалась по умолчанию. Так что, наконец, мне удастся найти лучшее решение, которое отлично работает, просто замените этот код строки:

let height = webView.stringByEvaluatingJavaScript(from: "document.body.scrollHeight")

Это мой окончательный полный код:

    func webViewDidFinishLoad(_ webView: UIWebView) {

    //webview height
    webView.frame.size.height = 1
    webView.frame.size = webView.sizeThatFits(.zero)
    webView.scrollView.isScrollEnabled = false
    let height = webView.stringByEvaluatingJavaScript(from: "document.body.scrollHeight")
    if let height = height {
        if let heightInt = Int(height) {
            let heightFloat = Float(heightInt)

            webViewHeightConstraint.constant = CGFloat(heightFloat)
        }
    }
    webView.scalesPageToFit = true
}

Ответ 5

Хорошо, я понял, что я делаю неправильно, поэтому теперь я знаю, как назвать эту функцию. Прежде всего, я должен был назвать UIWebViewDelegate в своем классе. Затем установите для моего var jobSkillView значение (jobSkillView.delegate = self). Теперь я сделал свою главную ошибку. В моем коде у меня был оператор if else, который я выбрал для моего func webViewDidLoad. Я должен был вынести его из этого утверждения и в фактический класс, чтобы переопределить мой фрейм для UIWebView. Говоря о фрейме **** НЕ ВЗЯТЬ, ЧТОБЫ УСТАНОВИТЬ ВЫСОТУ КАМЕРЫ 1. Тогда и только тогда эта функция будет работать для вашего UIWebView. После этого вы должны иметь полностью функциональную высоту для вашего UIWebView для Swift.

Ответ 6

Используйте следующий код, чтобы сделать динамическую динамику UIWebView в Swift 3.x

func webViewDidFinishLoad(_ webView: UIWebView) {        

 let height = webView.scrollView.contentSize.height
 var wRect = webView.frame
 wRect.size.height = height
 webView.frame = wRect

}

Ответ 7

вы можете использовать этот класс для масштабирования размера веб-просмотра, чтобы он соответствовал быстрым 3 и быстрым 4

//
//  RSWebView.swift
//  CustumWebViewDemo
//
//  Created by Ruchin Somal on 01/01/18.
//  Copyright © 2018 Ruchin Somal. All rights reserved.
//

import UIKit

class RSWebView: UIWebView, UIWebViewDelegate {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        self.scrollView.isScrollEnabled = false
        self.scrollView.bounces = false
        self.delegate = self
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.scrollView.isScrollEnabled = false
        self.scrollView.bounces = false
        self.delegate = self
    }

    override func loadHTMLString(_ string: String?, baseURL: URL?) {
        let s:String = "<html><head><title></title><meta name=\"viewport\" content=\"initial-scale=1, user-scalable=no, width=device-width\" /><link rel=\"stylesheet\" href=\"./webview.css\" ></link></head><body>"+string!+"</body></html>";
        var url:URL

        if baseURL == nil {
            url = Bundle.main.bundleURL
        } else {
            url = baseURL!
        }

        super.loadHTMLString(s, baseURL: url)
    }

    func webViewDidFinishLoad(_ webView: UIWebView) {
        self.webViewResizeToContent(webView: webView)
    }

    func webViewResizeToContent(webView: UIWebView) {
        webView.layoutSubviews()

        // Set to initial value of webview
        var frame:CGRect = webView.frame
        frame.size.height = 1.0
        webView.frame = frame

        // Calculated height of webview
        let wvheight: CGFloat = webView.scrollView.contentSize.height
        print("UIWebView.height: \(wvheight)")
        var wvRect = webView.frame
        wvRect.size.height = wvheight
        webView.frame = wvRect

        let heightConstraint = NSLayoutConstraint(item: webView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.height, multiplier: 1.0, constant: wvheight)
        webView.addConstraint(heightConstraint)

        webView.window?.setNeedsUpdateConstraints()
        webView.window?.setNeedsLayout()
    }

}

Ответ 8

При изменении шрифта в это время измените Webview height на 1, чем получите правильный offsetHeight для Webview

webView1.frame.size.height = 1

Ответ 9

Я использую строку HTML в своей загрузке и должен использовать следующий метод в делегате Webview:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
        self.webviewHeightConstraint?.constant = height as! CGFloat
    })
}

и полный код:

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

@IBOutlet weak var webviewHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var webview: WKWebView!
var observing = false

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    webview.navigationDelegate = self
    webview.scrollView.isScrollEnabled = false

        self.webview.loadHTMLString("""
        <html>
        <head>
        <style>
        ul {
        list-style: none;
        }

        ul li::before {
        content: "\\2022";
        color: red;
        font-weight: bold;
        display: inline-block;
        width: 1em;
        margin-left: -1em;
        }
        </style>
        </head>
        <body>

        <h2>Change Bullet Color of List Items</h2>

        <ul>
        <li>Adele</li>
        <li>Agnes</li>
        <li>Billy</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        <li>Bob</li>
        </ul>

        </body>
        </html>
""", baseURL: nil)
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
        self.webviewHeightConstraint?.constant = height as! CGFloat
    })
}

}