Кажется, что шаблоны объектов IB в XCode 6 beta все еще создают объекты старого стиля (UIWebView для iOS и WebView для OSX). Надеюсь, Apple обновит их для современного WebKit, но до тех пор, какой лучший способ создать WKWebViews в Interface Builder? Должен ли я создать базовое представление (UIView или NSView) и присвоить его тип WKWebView? Большинство примеров, которые я нахожу в Интернете, добавляются в контейнерный вид программно; почему-то лучше?
WKWebView в интерфейсе Builder
Ответ 1
Вы правы - это не работает. Если вы посмотрите в заголовках, вы увидите:
- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
что означает, что вы не можете создать экземпляр одного из ниба.
Вам придется делать это вручную в viewDidLoad или loadView.
Ответ 2
Как указано некоторыми, с Xcode 6.4 WKWebView по-прежнему недоступен в Interface Builder. Однако их очень легко добавить через код.
Я просто использую это в своем ViewController. Пропуск интерфейса построителя
import UIKit
import WebKit
class ViewController: UIViewController {
private var webView: WKWebView?
override func loadView() {
webView = WKWebView()
//If you want to implement the delegate
//webView?.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
if let url = URL(string: "https://google.com") {
let req = URLRequest(url: url)
webView?.load(req)
}
}
}
Ответ 3
Info.plist
добавьте в настройки безопасности транспорта Info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Xcode 9. 1+
Использование конструктора интерфейса
Вы можете найти элемент WKWebView в библиотеке объектов.
Добавить представление программно с помощью Swift 5
let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
view.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
webView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
Add view programmatically with Swift 5 (full sample)
import UIKit
import WebKit
class ViewController: UIViewController {
private weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
initWebView()
webView.loadPage(address: "http://apple.com")
}
private func initWebView() {
let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
view.addSubview(webView)
self.webView = webView
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
webView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
}
}
extension WKWebView {
func loadPage(address url: URL) { load(URLRequest(url: url)) }
func loadPage(address urlString: String) {
guard let url = URL(string: urlString) else { return }
loadPage(address: url)
}
}
Ответ 4
С Xcode 8 это теперь возможно, но средства достижения этого немного наименее взломаны. Но эй, рабочее решение - это рабочее решение, верно? Позвольте мне объяснить.
WKWebView initWithCoder: больше не аннотируется как "NS_UNAVAILABLE". Теперь он выглядит так, как показано ниже.
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
Начните с подклассификации WKWebView и переопределите initWithCoder. Вместо вызова супер initWithCoder вам нужно будет использовать другой метод init, такой как initWithFrame: configuration:. Быстрый пример ниже.
- (instancetype)initWithCoder:(NSCoder *)coder
{
// An initial frame for initialization must be set, but it will be overridden
// below by the autolayout constraints set in interface builder.
CGRect frame = [[UIScreen mainScreen] bounds];
WKWebViewConfiguration *myConfiguration = [WKWebViewConfiguration new];
// Set any configuration parameters here, e.g.
// myConfiguration.dataDetectorTypes = WKDataDetectorTypeAll;
self = [super initWithFrame:frame configuration:myConfiguration];
// Apply constraints from interface builder.
self.translatesAutoresizingMaskIntoConstraints = NO;
return self;
}
В вашей раскадровке используйте UIView и дайте ему собственный класс вашего нового подкласса. Остальное - это обычное дело (установка ограничений автоматической компоновки, привязка представления к розетке в контроллере и т.д.).
Наконец, WKWebView масштабирует контент по-разному для UIWebView. Многие люди, вероятно, захотят следовать простым советам в Подавить WKWebView от масштабирования контента для рендеринга с таким же увеличением, что и UIWebView, чтобы WKWebView более внимательно следил за поведением UIWebView в в этом отношении.
Ответ 5
Здесь простая версия Swift 3, основанная на crx_au отличном ответе.
import WebKit
class WKWebView_IBWrapper: WKWebView {
required convenience init?(coder: NSCoder) {
let config = WKWebViewConfiguration()
//config.suppressesIncrementalRendering = true //any custom config you want to add
self.init(frame: .zero, configuration: config)
self.translatesAutoresizingMaskIntoConstraints = false
}
}
Создайте UIView в Interface Builder, назначьте свои ограничения и назначьте его WKWebView_IBWrapper
как пользовательский класс, например:
Ответ 6
Теперь это, по-видимому, исправлено в Xcode 9b4. В примечаниях к выпуску говорится: "WKWebView доступен в библиотеке объектов iOS".
Я не смотрел глубже, чтобы узнать, требует ли он iOS 11 или обратно совместим.
Ответ 7
Если вы все еще сталкиваетесь с этой проблемой в последних версиях XCode, т.е. v9. 2+, просто импортируйте Webkit в свой ViewController:
#import <WebKit/WebKit.h>
Ответ 8
Вы можете создавать и настраивать WKWebView в IB начиная с Xcode 9, нет необходимости делать это в коде.
Обратите внимание, что ваша цель развертывания должна быть выше, чем iOS 10, иначе вы получите ошибку во время компиляции.
Ответ 9
В XCode версии 9.0.1 WKWebView доступен в Interface Builder.
Ответ 10
Я связал WebKit, теперь он работает!
Ответ 11
Это работало для меня в Xcode 7.2...
Сначала добавьте веб-представление в качестве выхода UIWebView в раскадровку /IB. Это даст вам следующее свойство:
@property (weak, nonatomic) IBOutlet UIWebView *webView;
Затем просто измените свой код, чтобы изменить его на WKWebView.
@property (weak, nonatomic) IBOutlet WKWebView *webView;
Вы также должны изменить пользовательский класс на WKWebView в инспекторе идентификации.