【问题标题】:WKWebView bottom constraint set but doesn't workWKWebView 底部约束设置但不起作用
【发布时间】:2019-08-23 09:44:38
【问题描述】:

我已将WKWebView 底部约束设置为超级视图,但直到超级视图才会显示,而是将内容显示到安全区域。

这是显示底部未正确填充的问题图像。

这是视图和约束图像的层次结构

以及使用容器视图设置 WebView 约束的代码

    let wv = WKWebView(frame: containerView.frame, configuration: wvConfig)
    webView = wv
    containerView.addSubview(wv)
    
    // setup constraints
    wv.translatesAutoresizingMaskIntoConstraints = false
    if #available(iOS 11.0, *) {
        wv.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
        wv.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
        wv.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        wv.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
    } else {
        NSLayoutConstraint(item: wv, attribute: .top, relatedBy: .equal, toItem: containerView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .trailing, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .bottom, relatedBy: .equal, toItem: containerView, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
    } 

那么,任何人都可以在这里纠正这个问题吗?

某些特定 URL 的作品,但不是全部。为什么?

【问题讨论】:

  • 如果问题出在添加的视图中或父视图中,您能否指定背景颜色或其他内容?
  • else 是什么情况??您创建了一些约束,什么都不做,我认为您应该将约束分配给变量,然后使用 self.view.addConstraint(constY) 将变量添加到视图中
  • @ΒασίληςΔ.else 情况也很好,只是底部似乎没有超出安全区域。 isActive 表示在视图中添加约束。我认为您应该检查有关该文档的文档
  • 问题可能出在容器视图而不是 Web 视图中吗?正如其他人建议的那样,您可以尝试为容器视图设置红色背景,并查看视图是否覆盖整个屏幕。
  • @Cristik 已经尝试过了并检查了约束截图和第一个约束,它已经附在超级视图底部

标签: ios swift wkwebview


【解决方案1】:

以下子类 WKWebView 可能会解决您的问题:

class FullScreenWKWebView: WKWebView {

    override var safeAreaInsets: UIEdgeInsets {
        if #available(iOS 11.0, *) {
            let insects = super.safeAreaInsets
            return UIEdgeInsets(top: insects.top, left: insects.left, bottom: 0, right: insects.right)
        } else {
            return .zero
        }

    }
    override var alignmentRectInsets: UIEdgeInsets{
        let insects = super.alignmentRectInsets
        return UIEdgeInsets(top: insects.top-20, left: insects.left, bottom: 0, right: insects.right)
    }
}

以上截取from

完整代码:

import UIKit
import WebKit
class FullScreenWKWebView: WKWebView {

    override var safeAreaInsets: UIEdgeInsets {
        if #available(iOS 11.0, *) {
            let insects = super.safeAreaInsets
            return UIEdgeInsets(top: insects.top, left: insects.left, bottom: 0, right: insects.right)
        } else {
            return .zero
        }

    }
    override var alignmentRectInsets: UIEdgeInsets{
        let insects = super.alignmentRectInsets
        return UIEdgeInsets(top: insects.top-20, left: insects.left, bottom: 0, right: insects.right)
    }
}
class ViewController: UIViewController {

    let contaienrView: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    let webView: FullScreenWKWebView = {
        let v = FullScreenWKWebView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    func setupViews(){
        view.addSubview(contaienrView)
        contaienrView.addSubview(webView)
        let constrains = [
            contaienrView.topAnchor.constraint(equalTo: view.topAnchor),
            contaienrView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            contaienrView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            contaienrView.trailingAnchor.constraint(equalTo: view.trailingAnchor),

            webView.topAnchor.constraint(equalTo: contaienrView.topAnchor),
            webView.leadingAnchor.constraint(equalTo: contaienrView.leadingAnchor),
            webView.bottomAnchor.constraint(equalTo: contaienrView.bottomAnchor),
            webView.trailingAnchor.constraint(equalTo: contaienrView.trailingAnchor),
            ]
        NSLayoutConstraint.activate(constrains)
    }

    func loadRequest(){
        let url = URL(string: "https://afghan-gps.com/mobile")!
        let request = URLRequest(url: url)
        webView.load(request)
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        loadRequest()
    }
}

输出:1. iOS 版本 > 10

  1. iOS版本

【讨论】:

  • 问题是,我只需要底部约束不使用安全区域但顶部使用它
  • @EICaptainv2.0 你可以根据自己的需求调整FullScreenWKWebView中safeAreaInsets的值
  • @EICaptainv2.0 给我一分钟
  • 但我的问题是,如果 containerview 在故事板中,它是如何工作的?
【解决方案2】:

我正在尝试重现相同的问题,使用了您的方法,但没有遇到任何关于底部空间的问题。

class TestWebViewController: UIViewController{

@IBOutlet weak var containerView: UIView!

var wkWebView : WKWebView?

override func viewDidLoad() {
    super.viewDidLoad()
    addWKWebView()

    wkWebView?.load(URLRequest(url: URL(string: "https://www.google.com")!))
    wkWebView?.allowsBackForwardNavigationGestures = true

    // Do any additional setup after loading the view.
}

func addWKWebView() {
    let wvConfig = WKWebViewConfiguration.init()
    let wv = WKWebView(frame: containerView.frame, configuration: wvConfig)
    wkWebView = wv
    containerView.addSubview(wv)
    // setup constraints
    wv.translatesAutoresizingMaskIntoConstraints = false
    if #available(iOS 11.0, *) {
        wv.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
        wv.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
        wv.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        wv.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
    } else {
        NSLayoutConstraint(item: wv, attribute: .top, relatedBy: .equal, toItem: containerView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .trailing, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: wv, attribute: .bottom, relatedBy: .equal, toItem: containerView, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
    }
}
}

对我来说一切都很好。

输出 -

如果我遗漏了什么,请告诉我。

更新 -

问题在于 WKWebview 的滚动视图。

在安全区域 WKScrollView.adjustedContentInset 设置为 {0, 0, 34, 0}。

为了避免这种使用

wv.scrollView.contentInsetAdjustmentBehavior = .never

最终输出 -

【讨论】:

  • 是的,但我所做的不是同一件事吗?
  • 请检查已编辑的问题并使用我提供的 URL 并告诉我
  • 最后我找出了问题所在,请检查更新的答案。
  • 但是 top insets 在这个 scnario 中表现不佳
【解决方案3】:

将 containerview 替换为底部约束中的视图,因为根是视图。

 view.addSubview(wv)

  wv.translatesAutoresizingMaskIntoConstraints = false
    if #available(iOS 11.0, *) {
        wv.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
        wv.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
        wv.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
        wv.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }
    NSLayoutConstraint(item: wv, attribute: .top, relatedBy: .equal, toItem: containerView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: wv, attribute: .leading, relatedBy: .equal, toItem: containerView, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: wv, attribute: .trailing, relatedBy: .equal, toItem: containerView, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
            NSLayoutConstraint(item: wv, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true

【讨论】:

  • 但是ContainerView已经附加了superview.bottom。那么,为什么我们需要这个?
  • 我更新了我的答案。我们必须改变底部锚点。您正在使用 containerview 设置约束。将此设置为查看哪个是根元素
  • 将 containerView.addSubview(wv) 替换为 view.addSubview(wv)。因为容器视图就像安全区
  • 兄弟,它不像安全区域。请检查屏幕截图是否有限制。容器视图附在superview的底部。
  • 查看containerview的不同之处,查看有助于解决这个问题
【解决方案4】:

您的代码看起来不错,您的问题可能来自containerView 约束。

如果您使用情节提要,Xcode 可能会设置安全区域的限制。在这种情况下,您应该以编程方式处理所有约束。

【讨论】:

  • 这是不可能的。如果我们用安全区域底部限制容器视图底部,那么无论它是什么(故事板或编码),都没有区别。
【解决方案5】:

根据给定的屏幕截图,底部约束应用于安全区域。将底部约束添加到 SuperView。

【讨论】:

  • 已经尝试过并检查约束截图和第一个约束,它已经附在超级视图底部
  • 我认为您的底部约束已应用于 ContainerView 底部。需要应用到SuperView中,请检查
  • 请检查上面代码的截图,它应用于superview的底部
  • Can you Change Bottom Alignment Constraint -> First item into ContainerView.Bottom and Second Item into Superview.Bottom (Reverse first item and second item i)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多