Динамическое изменение заголовка NSWindow во время работы приложения - PullRequest
1 голос
/ 04 марта 2020

Я хочу создать приложение, в котором заголовок NSWindow отражает значение заголовка страницы WKWebView. Однако у меня возникли проблемы с настройкой заголовка окна вне методов инициализатора, таких как viewDidLoad, viewWillAppear и т. Д. c. Вот что у меня пока есть:

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

    }
}

Что я делаю не так?

1 Ответ

2 голосов
/ 05 марта 2020

Вы создаете новый контроллер представления в своем наблюдателе:

ViewController().titleChange(pageTitle: title)

И вызываете titleChange() на нем. Итак, поскольку это новый контроллер, он не имеет windows и не имеет ничего общего с представленной в настоящее время иерархией представления.

Чтобы исправить это, обновите наблюдателя до чего-то вроде этого:

// 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 будет вызван на контроллере, который вы видите на экране.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...