在 iOS 10 + Swift 3 中以编程方式在我的 WKWebView 上方添加 UILabel

Posted

技术标签:

【中文标题】在 iOS 10 + Swift 3 中以编程方式在我的 WKWebView 上方添加 UILabel【英文标题】:Programmatically add a UILabel above my WKWebView in iOS 10 + Swift 3 【发布时间】:2017-01-28 18:53:05 【问题描述】:

据我了解,WKWebView 不能在情节提要中创建。我必须使用以下代码在我的 ViewController 实例之一中以编程方式创建它:

 override func loadView() 
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.navigationDelegate = self
        view = webView
 

我面临的问题是我想在webView 上方放置一个跨越设备宽度的 UILabel。在它的正下方,没有任何可见空间,我想要放置 webView。所以,如果我的标签是 20 像素高,那么从技术上讲,webView 的位置将比现在低 21 像素。

在情节提要中,这显然是一项微不足道的任务;它是如何以编程方式完成的?

【问题讨论】:

【参考方案1】:

André Slotta's Answer 应该使用Visual Format Language。我想展示另一个使用NSLayoutAnchor 的解决方案(提示在代码cmets 中)。第三种选择是NSLayoutConstraint。欲了解更多信息,您可以通过here 了解所有三个选项的概述

import UIKit
import WebKit


class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate 

  var webView: WKWebView!
  var label: UILabel!

  override var prefersStatusBarHidden: Bool 
    return true
  

  override func loadView() 
    super.loadView()

    setupLabel()

    let webViewConfiguration = WKWebViewConfiguration()
    webView = WKWebView(frame: .zero, configuration: webViewConfiguration)
    webView.translatesAutoresizingMaskIntoConstraints = false
    webView.uiDelegate = self
    webView.navigationDelegate = self
    let request = URLRequest(url: URL(string: "https://***.com/")!)
    webView.load(request)

    view.addSubview(webView)

    // x, y, width and height of the web view
    webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    // put the top anchor just below the bottom anchor of the label
    // with this the web view is directly below your label
    webView.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
    webView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true  
  

  func setupLabel() 
    label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.text = "label"
    label.backgroundColor = .gray
    label.textColor = .red
    view.addSubview(label)

    // x, y, width and height of the label
    label.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    label.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    // the height of your label (In your case 20 pixels)
    label.heightAnchor.constraint(equalToConstant: 20).isActive = true
  

结果:

【讨论】:

【参考方案2】:

如果您需要使用约束的解决方案,请执行以下操作:

class ViewController: UIViewController 
    var label: UILabel!
    var webView: WKWebView!

    override var prefersStatusBarHidden: Bool 
        return true
    

    override func viewDidLoad() 
        super.viewDidLoad()

        label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.backgroundColor = UIColor.lightGray
        label.text = "some text"

        let webViewConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webViewConfiguration)
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.backgroundColor = UIColor.darkGray

        let request = URLRequest(url: URL(string: "http://www.google.de")!)
        webView.load(request)

        view.addSubview(label)
        view.addSubview(webView)

        // horizontal constraints
        NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "|[label]|", options: [], metrics: nil, views: ["label": label]))
        NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "|[webView]|", options: [], metrics: nil, views: ["webView": webView]))

        // vertical constraints
        NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|[label][webView]|", options: [], metrics: nil, views: ["label": label, "webView": webView]))
    

这是它的样子:

【讨论】:

你测试过这个吗? webView 显示/渲染正常,但标签无处可见。 我有,我可以看到 :) 你删除了你的loadView() 代码吗? 我做到了。调查问题可能出在哪里。 'Unable to parse constraint format: Unable to interpret '|' character, because the related view doesn't have a superview |[label]| 您是否创建了标签并将其添加为子视图? view.addSubview(label)【参考方案3】:

您可以将 UILabel 和 WKWebView 添加到 UIScrollView 中。只需禁用 webview 上的滚动和弹跳,它应该会自动调整到 webview 的高度。

【讨论】:

【参考方案4】:

不要让WKWebView 成为视图控制器的视图,而是让WKWebView 成为viewController 视图的子视图。您可以在视图控制器的viewDidLoad 中执行此操作。

var webView: WKWebView!
let label = UILabel()

override func viewDidLoad() 
    super.viewDidLoad()

    let webConfiguration = WKWebViewConfiguration()
    webView = WKWebView(frame: .zero, configuration: webConfiguration)
    webView.uiDelegate = self
    webView.navigationDelegate = self
    view.addSubview(webView)

    ... // Other customization here
    view.addSubview(label)

然后在viewDidLayoutSubviews你可以手动定位视图

override func viewDidLayoutSubviews() 
    super.viewDidLayoutSubviews()

    webView.frame = ...
    label.frame = ...


【讨论】:

【参考方案5】:

这段代码可以在 ViewController 的大部分生命周期中完成,最好是在视图尚未呈现时(因此无论是 init、viewDidLoad、viewWillAppear)。

将高度为 20px 宽度为屏幕宽度的 UI 标签放置:

let label = UILabel(frame: CGRect(x: 0, y:0, width: view.frame.width, height: 20))
view.addSubview(label)

将 WKWebView 放在下方,因此 WKWebView 的原点为 (0, 20),高度为 (屏幕高度 - 20)

let wkWebView = WKWebView(frame: CGRect(x: 0, y:20, width: view.frame.width, height : view.frame.height - 20))
view.addSubview(wkWebView)

这里的view 是 ViewController 本身的视图。

差不多了!您可以通过更改视图本身的框架来布局视图,然后将其添加为主视图的子视图。如果您想要灵活的视图,那么您将不得不手动实现一些 LayoutConstraint 代码,这比这要复杂得多。

【讨论】:

【参考方案6】:

如果您使用MarkupKit,您可以按如下方式完成:

<LMColumnView spacing="0">
    <UILabel text="This is the label" textAlignment="center" backgroundColor="#eeeeee"/>
    <WKWebView id="webView" weight="1"/>
</LMColumnView>

【讨论】:

以上是关于在 iOS 10 + Swift 3 中以编程方式在我的 WKWebView 上方添加 UILabel的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ios swift 中以编程方式创建自动布局等宽约束?

在 iOS Swift 3 中以编程方式添加 Web 视图时如何在 UIWebView 中获取响应状态代码?

如何在ios swift中以编程方式创建自动布局等宽度约束?

如何使用 Swift 在 iOS 中以编程方式进行 segue

我可以在 Swift 5 和 IOS 12 中以编程方式更改 iOS 屏幕壁纸吗

在 Swift 中以编程方式从 MainViewController 切换到 .xib 视图?