Как настроить 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()
?
Ответы
Ответ 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.