nib
中的 UIWebView
连接到视图控制器中的一个插座(outlet)。UIScrollView
、在 Web 视图上方的 UIView
(在我的示例中,我省略了该视图中的所有标签)以及 UIWebView
设置约束。height
约束连接到视图控制器中的插座(outlet)。UIWebViewDelegate
。webViewDidFinishLoad
中,将高度约束的常量设置为 Web 视图内滚动视图的 contentSize
的高度。contentSize
以更改高度,当 Web 页面的某些部分因未重新加载页面而改变其大小时(例如手风琴或菜单)就需要更改 Web 视图的高度。我不会详细解释约束,因为您似乎已经自己弄清楚了。以下是约束的截图:
所以,以下是代码:
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()
}
}
}
来自@joern的绝妙解决方案。对我很有效。我只是将他的代码改成了Swift 3。
Swift 3更新代码:
我还修改了stopObservingHeight以防止在创建之前删除观察者。
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()
}
}
}
case("contentSize", &MyObservationContext):
中加入 let context = context
到 guard
语句中将解决错误。非常好的更新! - John Pang
webViewDidFinishLoad
时更新约束,最终只能显示屏幕上能容纳的部分。如果只在最后一次调用(webView.isLoading == false
)时更新约束,则可以获取几乎整个页面,但末尾会被截断。 - Julian F. WeinertwebViewDidFinishLoad
的调用,或者它太早了,我不确定。但是当我每次加载HTML时添加观察者,一切都正常!肯定有些愚蠢的地方我没看到。干得好,非常感谢! - Julian F. Weinert