我想创建一个应用程序,其中NSWindow的标题反映WKWebView的页面标题值。但是,在设置初始化方法(例如viewDidLoad,viewWillAppear等)之外的窗口标题时,我一直遇到麻烦。这是到目前为止的内容:
ViewController.swift
import Cocoa
import WebKit
class ViewController: NSViewController, WKUIDelegate, WKNavigationDelegate, NSWindowDelegate {
@IBOutlet var webView: WKWebView!
var webViewTitleObserver: NSKeyValueObservation?
let windowController: WindowController = WindowController()
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
webView.uiDelegate = self
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
preferences.javaScriptCanOpenWindowsAutomatically = true
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
webView.load("https://google.com")
// WebView Title Observer
webViewTitleObserver = self.observe(\.webView.title, options: .new) { webView, change in
let title = "\(String(describing: change.newValue))"
ViewController().titleChange(pageTitle: title)
}
}
override func viewWillAppear() {
self.view.window?.delegate = self
}
func titleChange(pageTitle: String) {
//self.view.window?.delegate = self
print("Start Title:", pageTitle)
// Fix Optional URL String
var title = pageTitle.replacingOccurrences(of: "Optional", with: "")
let brackets: Set<Character> = ["(", ")"]
title.removeAll(where: { brackets.contains($0) })
print("Clean Title:", title)
self.view.window?.title = title
self.view.window?.update()
}
}
// MARK: Extensions
// WKWebView Extension
extension WKWebView {
func load(_ urlString: String) {
if let url = URL(string: urlString) {
let request = URLRequest(url: url)
load(request)
}
}
}
目前,只要更改标题,此代码就会打印到控制台,因此页面标题将照此显示:
Start Title: Optional(Optional("Google"))
Clean Title: "Google"
但是,窗口的标题拒绝在titleChange函数中更改。为什么会这样?
WindowController.swift(如果需要)
import Cocoa
class WindowController: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
super.windowDidLoad()
window!.delegate = self
window!.titlebarAppearsTransparent = true
window!.isMovableByWindowBackground = true
}
}
有人可以提供一些有关我做错了什么的指导吗?任何帮助表示赞赏!预先谢谢!
您将在观察者中创建一个新的视图控制器:
ViewController().titleChange(pageTitle: title)
然后调用titleChange()
。因此,因为这是一个新的控制器,所以它没有窗口,并且与当前显示的控制器无关。
要修复它,请将观察者更新为类似这样的内容:
// WebView Title Observer
webViewTitleObserver = self.observe(\.webView.title, options: .new) { [weak self] webView, change in
let title = "\(String(describing: change.newValue))"
self?.titleChange(pageTitle: title)
}
我更改了参数,并捕获了weak
的self
参考,然后在其上调用titleChange()
函数。在这种情况下,将在显示的视图控制器上调用self.view.window?.title = title
。