Ios 使用自动布局使UIWebView的高度与其内容相同

Ios 使用自动布局使UIWebView的高度与其内容相同,ios,swift,uiwebview,autolayout,Ios,Swift,Uiwebview,Autolayout,我在滚动视图中嵌入了一个web视图,我希望web视图“扩展”以显示其所有内容,然后我希望使用滚动视图滚动浏览这些内容 我之所以使用滚动视图作为超级视图,而不仅仅是使用web视图作为滚动视图,是因为我想在滚动过程中包含web视图上方的标签(请参见屏幕截图) 那么,如何使webview自身调整大小,从而占用显示其包含的内容所需的所有空间呢 在那之后,我如何使superview(滚动视图)根据webview的大小调整自身大小 要完成此工作,您必须执行以下步骤: 将UIWebView从nib连接到视图

我在滚动视图中嵌入了一个web视图,我希望web视图“扩展”以显示其所有内容,然后我希望使用滚动视图滚动浏览这些内容

我之所以使用滚动视图作为超级视图,而不仅仅是使用web视图作为滚动视图,是因为我想在滚动过程中包含web视图上方的标签(请参见屏幕截图)

那么,如何使webview自身调整大小,从而占用显示其包含的内容所需的所有空间呢

在那之后,我如何使superview(滚动视图)根据webview的大小调整自身大小


要完成此工作,您必须执行以下步骤:

  • UIWebView
    从nib连接到视图控制器中的插座
  • 禁用web视图中的滚动
  • UIScrollView
    上设置约束,在web视图顶部设置
    UIView
    (在我的示例中,我省略了该视图中的所有标签)和
    UIWebView
  • 将UIWebView的
    高度
    约束连接到视图控制器中的插座
  • 将视图控制器设置为
    UIWebViewDelegate
  • webViewDidFinishLoad
    中,将高度约束的常量设置为web视图中滚动视图的
    contentSize
    的高度
  • 当web视图的高度必须更改时,启动contentSize上的键值以更改高度,因为网页的段在不重新加载页面(如手风琴或菜单)的情况下更改其大小
  • 我不会详细解释这些限制,因为您似乎已经自己解决了它们。以下是约束条件的屏幕截图:

    下面是代码:

    import UIKit
    
    var MyObservationContext = 0
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var webview: UIWebView!
        @IBOutlet weak var webviewHeightConstraint: NSLayoutConstraint!
        var observing = false
    
        override func viewDidLoad() {
            super.viewDidLoad()
            webview.scrollView.scrollEnabled = false
            webview.delegate = self
            webview.loadRequest(NSURLRequest(URL: NSURL(string: "https://www.google.de/intl/de/policies/terms/regional.html")!))
        }
    
        deinit {
            stopObservingHeight()
        }
    
        func startObservingHeight() {
            let options = NSKeyValueObservingOptions([.New])
            webview.scrollView.addObserver(self, forKeyPath: "contentSize", options: options, context: &MyObservationContext)
            observing = true;
        }
    
        func stopObservingHeight() {
            webview.scrollView.removeObserver(self, forKeyPath: "contentSize", context: &MyObservationContext)
            observing = false
        }
    
        override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
            guard let keyPath = keyPath else {
                super.observeValueForKeyPath(nil, ofObject: object, change: change, context: context)
                return
            }
            switch (keyPath, context) {
            case("contentSize", &MyObservationContext):
                webviewHeightConstraint.constant = webview.scrollView.contentSize.height
            default:
                super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
            }
        }
    }
    
    extension ViewController: UIWebViewDelegate {
        func webViewDidFinishLoad(webView: UIWebView) {
            print(webView.request?.URL)
            webviewHeightConstraint.constant = webview.scrollView.contentSize.height
            if (!observing) {
                startObservingHeight()
            }
        }
    }
    
    导入UIKit
    var MyObservationContext=0
    类ViewController:UIViewController{
    @ibvar-webview:UIWebView!
    @IBOutlet弱var webviewHeightConstraint:NSLayoutConstraint!
    var=false
    重写func viewDidLoad(){
    super.viewDidLoad()
    webview.scrollView.scrollEnabled=false
    webview.delegate=self
    loadRequest(NSURLRequest)(URL:NSURL(字符串:)https://www.google.de/intl/de/policies/terms/regional.html")!))
    }
    脱硝{
    stopObservingHeight()
    }
    func startObservingHeight(){
    let options=NSKeyValueObservingOptions([.New])
    webview.scrollView.addObserver(self,forKeyPath:“contentSize”,选项:选项,上下文:&MyObservationContext)
    观察=真实;
    }
    func stopObservingHeight(){
    webview.scrollView.removeObserver(self、forKeyPath:“contentSize”、context:&MyObservationContext)
    观察=错误
    }
    重写func observeValueForKeyPath(键路径:String?,对象对象的类型:AnyObject?,更改:[String:AnyObject]?,上下文:UnsafeMutablePointer){
    guard let keyPath=keyPath else{
    super.observeValueForKeyPath(nil,of对象:object,change:change,context:context)
    返回
    }
    开关(键路径、上下文){
    案例(“contentSize”和MyObservationContext):
    webviewHeightConstraint.constant=webview.scrollView.contentSize.height
    违约:
    super.observeValueForKeyPath(键路径,of对象:object,change:change,context:context)
    }
    }
    }
    扩展视图控制器:UIWebViewDelegate{
    func webViewDidFinishLoad(webView:UIWebView){
    打印(webView.request?.URL)
    webviewHeightConstraint.constant=webview.scrollView.contentSize.height
    如果(!观察){
    开始工作高度()
    }
    }
    }
    
    来自的伟大解决方案。对我来说很好。我刚把他的密码改成了swift 3

    Swift 3更新代码:

    我还修改了stopObservingHeight,以防止在创建observer之前删除它

    import UIKit
    
    var MyObservationContext = 0
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var webview: UIWebView!
        @IBOutlet weak var webviewHeightConstraint: NSLayoutConstraint!
        var observing = false
    
        override func viewDidLoad() {
            super.viewDidLoad()
            webview.scrollView.isScrollEnabled = false
            webview.delegate = self
            webview.loadRequest(NSURLRequest(URL: NSURL(string: "https://www.google.de/intl/de/policies/terms/regional.html")!))
        }
    
        deinit {
            stopObservingHeight()
        }
    
        func startObservingHeight() {
            let options = NSKeyValueObservingOptions([.new])
            webview.scrollView.addObserver(self, forKeyPath: "contentSize", options: options, context: &MyObservationContext)
            observing = true;
        }
    
        func stopObservingHeight() {
            if observing {
                webView.scrollView.removeObserver(self, forKeyPath: "contentSize", context: &MyObservationContext)            
                observing = false
            }
        }
    
        override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            guard let keyPath = keyPath,
                let context = context else {
                super.observeValue(forKeyPath: nil, of: object, change: change, context: nil)
                return
            }
            switch (keyPath, context) {
            case("contentSize", &MyObservationContext):
                webviewHeightConstraint.constant = webview.scrollView.contentSize.height
            default:
                super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
            }
        }
    }
    
    extension ViewController: UIWebViewDelegate {
        func webViewDidFinishLoad(_ webView: UIWebView) {
            print(webView.request?.url ?? "nil")
            webviewHeightConstraint.constant = webview.scrollView.contentSize.height
            if (!observing) {
                startObservingHeight()
            }
        }
    }
    

    嘿当你最初发布答案时,我看到了你的答案,但当我准备开发我的应用程序的第二个版本时,我决定解决这个问题。非常感谢,我只是试着修复一切,效果很好。我只需要修正一些约束值来垂直偏移scrollView(因为我在顶部还有一个导航栏,它并不是一个空的superview)。这是我第一次在观察者中使用代码,所以我以后将不得不更仔细地研究它,但就目前而言,它是有效的!谢谢你的反馈,我很高兴它对你有帮助。非常感谢你的反馈Hi joern,回答得好。我很好奇为什么在这个例子中MyObservationContext是全局的。它似乎也可以作为类级变量使用。你能帮我照一下这个吗?谢谢+你好,丹。没错,它应该是一个类属性。没有理由让它全球化。谢谢你的评论!将
    let context=context
    添加到
    guard
    将解决
    案例中的错误(“contentSize”和&MyObservationContext):
    。伟大的更新!