Подтвердить что ты не робот

Как настроить WKWebView для заполнения NSWindow?

У меня есть небольшое прототипное приложение, разработанное в Swift с XCode 7.2. Приложение было создано как приложение Cocoa на основе документов с раскадрой. Таким образом, проект содержит AppDelegate.swift, Document.swift и Main.storyboard, все из которых не изменены из того, что генерируется XCode, и ViewController.swift, который содержит это:

import Cocoa
import WebKit

class ViewController: NSViewController {

    var webView: WKWebView {
        return view as! WKWebView
    }

    override func loadView() {
        view = WKWebView(/*frame: CGRect(x: 0, y: 0, width: 200, height: 200)*/)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        webView.loadHTMLString("<html><body><p>Hello, World!</p></body></html>", baseURL: nil)
    }
}

Я переопределил loadView(), чтобы непосредственно создать a WKWebView и назначить ему свойство view ViewController в качестве корневого представления, а не загружать представление, определенное в раскадровке.

Обратите внимание, что аргумент frame для WKWebView может быть прокомментирован или отсутствовать, чтобы продемонстрировать различные типы поведения, которые лежат в основе этого вопроса.

Желаемое поведение

A WKWebView экземпляр должен заполнить окно, соответствующее каждому документу, а начальный размер и положение новых окон документа должны быть такими, которые определены для NSWindow в раскадровке (480x270 на (196, 240)). WKWebView должен изменить размер с закрывающим окном.

Наблюдаемое поведение

Без аргумента frame

Без аргумента frame при запуске приложения не отображается окно документа, хотя в меню "Окно" отображается, что был создан документ "Без названия". Также не отображаются окна документа, когда дополнительные документы (Untitled 2 и т.д.) Создаются с помощью файлa > Создать.

Однако, если документ отображается в полноэкранном режиме с помощью "Просмотр" > "Ввод полного экрана", WKWebView и его приветствие отображаются, как ожидалось.

С аргументом frame

С аргументом frame окна документа, содержащие WKWebView и его приветствие, отображаются в размере и позиции, указанной в CGRect.

Вопрос

Я не понимаю, почему, когда кадр WKWebView не указан, представление принудительно добавляется к размеру контейнера (экрана) в полноэкранном режиме, но в оконном режиме противоположное, по-видимому, происходит: Окно вынуждено (выродить?) Размер представления, и поэтому становится невидимым. Я ожидал, что новые взгляды примут размер окна, как определено в раскадровке.

В моем ViewController, как мне настроить экземпляры WKWebView для заполнения NSWindow рамки документа, соответствующие каждому NSDocument? Или, возможно, мой подход неверен, и я должен включить настройку размера начального окна с помощью размера представления в ViewController.loadView()?

4b9b3361

Ответ 1

Попробуйте этот метод. Сначала вы должны вызвать super.loadView(). Это даст вам начальный размер представления, загружаемого из раскадровки. Затем вы меняете представление на веб-представление, используя рамку исходного вида. Надеюсь, это решает вашу проблему.

override func loadView() {
    super.loadView()
    view = WKWebView(frame:self.view.frame)
}

Вы также можете попробовать установить цвет фона веб-представления, чтобы увидеть, что он работает.

webView.loadHTMLString("<html><body bgcolor=red><p>Hello, World!</p></body></html>", baseURL: nil)

Ответ 2

Итак, моя первая реакция была: почему бы вам просто не добавить WKWebView в раскадровку? Таким образом, вы можете настроить размер так, чтобы он был размером с закрывающимся окном. Оказывается, вы не можете добавить WKWebView в Interface Builder (вот почему я думаю, вам нужно было пройти этот маршрут).

loadView по умолчанию подключает созданный экземпляр вида от элемента nib к свойству view контроллера вида. Проблема с переопределением loadView и последующим назначением self.view заключается в том, что он нарушает отношения раскадровки, которые содержимое окна имеет с вашим ViewController.

Итак, решение состоит в том, чтобы дождаться загрузки self.view из раскадровки, а затем добавить WKWebView в качестве подзаголовка:

- (void)viewDidLoad {
    WKWebView *wb = [[WKWebView alloc] initWithFrame:self.view.frame];
    [wb loadHTMLString:@"<html><body><p>Hello, World!</p></body></html>" baseURL:nil];
    [self.view addSubview:wb];
}

У меня есть только Objective-C. Извините, еще не научился Swift.